尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpringBoot+Vue高校社团管理系统毕设全流程指南

SpringBoot+Vue高校社团管理系统毕设全流程指南 简介这是一套面向高校社团管理场景的前后端分离Java项目基于Spring Boot与Vue设计实现适合正在准备毕业设计、课程设计或期末大作业的计算机专业学生也适合需要项目实战练习的Java学习者。整个压缩包为RAR格式共813个文件大小约27.94MB包含199个Java源码文件、141个Vue组件、159个SVG图标以及SQL数据库脚本、XML配置、CSS样式和JavaScript脚本等覆盖项目运行所需的完整工程与素材。目前已有48人学习浏览项目经严格调试保证可运行环境基于JDK1.8、MySQL5.7和Maven3.3相关依赖与工具版本清晰方便本地复现。包内还提供数据库脚本、开发说明文档、部署视频和代码讲解视频并附有文档与源码目录结构方便读者对照学习前后端交互逻辑、MyBatis持久层实现与后台管理功能。项目自带完整的工程骨架和批处理脚本可直接修改复用或作为毕业设计答辩支撑。1. 高校社团管理系统为什么选 springboot vue 做毕设最省心如果你的毕设题目是“基于 springboot vue 的高校社团管理系统”选这个方向算踩在了一个性价比不错的位置。社团管理系统的业务模型是淘宝、OA 的缩小版有用户、角色、审批、活动报名、数据统计但每一项都不至于复杂到失控。Java 毕业设计里springboot 给后端接口、vue 给前端页面是目前最主流的组合网上参考代码多答辩老师也认这套技术栈。这个系统要解决的核心问题是学生申请加入社团、社长审核成员、团委审批活动把原本靠纸质表格的流程搬到 Web 上。适合 Java 基础尚可、想拿中等偏上成绩又不愿意只写增删改查的同学。下面从拿到 .rar 开始把环境配置、前后端联调、答辩验收完整捋一遍。2. 拿到 .rar 先拆结构项目分层、技术选型与数据库设计很多同学拿到压缩包的第一反应是双击解压、用 IDEA 打开、等依赖、然后卡在报错里。我的习惯正好相反先拆目录、再看配置文件、最后启动。一个 springboot vue 的前后端分离项目能不能顺利跑起来在你动手前就能判断个八九不离十。这一章把「怎么看压缩包」和「为什么要这么选」讲清楚后面联调时会省掉一半的玄学排错。2.1 压缩包里常见的长这样后端、前端、SQL、文档这类毕业设计压缩包的目录结构大同小异。我经手的几个版本基本都是这个骨架高校社团管理系统/ ├── club-server/ # Spring Boot 后端目录 │ ├── src/ │ │ ├── main/ │ │ │ ├── java/com/xx/club/ │ │ │ └── resources/application.yml │ ├── pom.xml ├── club-web/ # Vue 前端目录 │ ├── src/ │ ├── package.json │ ├── vue.config.js │ └── .env.development ├── sql/ │ └── club.sql # 建表语句 初始管理员账号 └── 需求文档.doc注意不同作者的命名不一样有的后端叫server、前端叫front但规律不变后端、前端、SQL 脚本、说明文档这四样必须齐全。如果sql目录缺失你后面就要自己建表工作量直接翻倍如果有sql但没有vue.config.js前端转发规则大概率没配联调时跨域问题会接踵而至。拿到手先做三件体检用java -version确认 JDK 版本。项目pom.xml里parent的java.version如果是 1.8就用 JDK 8如果是 11 或 17就用对应版本版本不匹配是最常见的启动秒退原因。用mysql -V确认 MySQL 版本。application.yml里驱动是com.mysql.cj.jdbc.Driver一般配 MySQL 5.7 或 8.0 都行但 5.7 和 8.0 的密码加密规则有差异5.7 的配置文件连 8.0 数据库经常报Public Key Retrieval错。用node -v确认前端环境。Vue 2 项目建议 Node 14 或 16Vue 3 Vite 建议 Node 16 以上太老的 Node 装依赖会卡在node-sass这属于 vue 安装依赖阶段最典型的翻车点。如果你打开压缩包看到后端没有pom.xml而是一个.classpath加WebContent的目录那多半是老的 Eclipse 工程不是 springboot 项目需要转换工程类型这件事比较麻烦。普通 springboot vue 毕设八成不会是那种结构。另外如果pom.xml里的 springboot 版本是 3.x那你的 JDK 必须切到 17不要因为本机装了 JDK 8 就顺手用 8控制台会直接告诉你找不到主类或无法加载javax.servlet相关类。2.2 为什么是 springboot vue职责边界与替换方案社团管理系统本质上是一套「角色 审批 信息发布」的管理后台。学生注册、社长管理成员、团委审核活动这些功能拆开看都是对数据库表的增删改查但合在一起就需要一个能支撑 RESTful 接口、权限拦截和状态流转的后端框架。springboot 之所以是 Java 毕业设计里的主流选型是因为它把 Tomcat 内嵌了不需要单独部署 Web 容器spring-boot-starter-web一个依赖就解决接口、数据校验、异常处理的大部分模板代码。对基础一般的同学来说只要会写 controller、service、mapper 三层剩下的自动装配可以暂时当作黑匣子。vue 在前端承担的是页面路由、组件复用和状态展示。社团列表页、活动详情页、审批操作页每个页面都是一个组件路由跳转时不再刷新整个页面操作体验比 JSP 时代顺畅得多。更重要的是vue 的响应式数据绑定让表单提交和列表刷新变得很直接你只要把后端返回的{ code, message, data }结构塞给data页面就会自动变。这个组合的职责边界非常清楚springboot 管数据验证、权限校验、业务逻辑和数据库读写vue 管页面结构、交互响应和路由跳转。中间通过 JSON 格式的 HTTP 接口通信。答辩老师喜欢问「为什么前后端分离」你可以回答后端不再关心页面渲染前端不再关心数据库连接两端都可以独立开发、独立部署也方便后续移动端复用同一套接口。如果换成 SSM 加 JSP你可以少学一个前端框架但写页面时会陷入jstl标签和EL表达式界面观感明显落后一个时代如果换成 Vue 加 Spring Cloud技术栈又偏重对毕设来说复杂度失控。springboot vue 恰好卡在「能完整解释一个有安全边界、有业务闭环的系统」和「工作量不用熬通宵」之间。另外要提醒一句如果压缩包里用的是 MyBatis-Plus你的mapper.xml会少很多如果是纯 MyBatis每张表都要配 resultMap。这个问题影响你后续改代码的时间建议打开后端pom.xml确认一下。2.3 数据库表设计社团、成员、活动、审批这四张核心表前端页面长得再花核心还是后端数据模型。高校社团管理系统一般至少有以下四张核心表club社团表字段包括名称、分类、简介、社长用户ID、状态。状态字段决定这个社团是否在前端列表可见通常 0 表示禁用1 表示正常。member成员表也是学生与社团的关联表字段包括用户ID、社团ID、加入时间、身份社长/管理员/普通成员。这张表解决「一个学生可以加入多个社团一个社团有多个学生」的多对多关系。activity活动表字段包括活动名称、地点、时间、预算、发起社团ID、审核状态。审核状态是这套系统的业务核心待审核、已通过、已驳回。audit审批记录表保存审批人ID、审批意见、审批时间以及活动ID。有这张表你才能在详情页展示「谁在什么时间批了什么意见」答辩时说明这是一条完整的审计链。数据库关系可以概括为club和user通过member表关联activity通过club_id归属到社团audit通过activity_id回看审批历史。这里有一个我踩过的坑很多毕设把审批状态直接放在activity表里这没问题但如果还要记录两次驳回再提交的历史就必须有独立的审批记录表。在写代码之前最好先打开sql/club.sql确认一下各表有没有create_time、update_time这类时间字段以及deleted逻辑删除标记。没有的话列表排序和「社团被误删后恢复数据」会是后续开发的硬伤。你会发现把数据库设计讲顺了后面的 controller 和页面都是体力活。3. 本地跑通后端建库、改配置、启动与登录鉴权后端是整个系统的中枢也是大部分同学第一次接触 springboot 项目时会卡住的地方。这一章只讲三件事把数据库灌进去把配置文件改成自己能跑把登录认证链路的代码看懂。后端跑通的标志不是控制台出现 spring 的 Logo而是登录接口向后端要到了 token。3.1 先建库再配 application.yml三个必改参数先建库再导数据。不要在 Navicat 里直接双击执行一个包含CREATE DATABASE的脚本有些 SQL 文件开头没有建库语句你会在错误日志里看到Unknown database。我的做法是在命令行完成建库和导入mysql -uroot -p -e CREATE DATABASE IF NOT EXISTS club_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; mysql -uroot -p club_db sql/club.sqlutf8mb4必须用因为社团简介、活动详情里可能会出现表情符号用utf8在 Java 程序里读出来会显示??。导入成功后用show tables确认有club、member、activity、sys_user这类表。接下来改后端资源配置文件server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/club_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml type-aliases-package: com.example.club.entity jwt: secret: 请改成至少32位的随机字符串 expire-hours: 24serverTimezoneAsia/Shanghai是为了不差 8 小时allowPublicKeyRetrievaltrue是 MySQL 8.0 用户必须加的否则登录接口会报Public Key Retrieval is not allowed。password改成你自己的数据库密码这是毕业设计中翻车率最高的一行配置。如果本机 MySQL 用户校验插件是caching_sha2_password而你用的驱动版本老重启后也容易报同样的问题最简单的处理就是升级mysql-connector-java到 8.0.33 以上或者换个 MySQL 5.7 环境。这里有个容易被忽略的参数server.port。如果改成了 8081前端 request.js 里的请求地址也要同步改否则前端页面能打开但所有接口都连不上。后端启动看到Tomcat started on port(s): 8080只代表端口起来了不代表业务没问题真正的验证在第 3.3 节。3.2 登录接口与拦截器JWT 在毕业设计里怎么用才不露怯社团管理系统的权限模型一般是三种角色学生、社长/社团管理员、团委管理员。登录成功后的身份信息要传给后面的每个接口常见做法是用 JWT。先看登录接口RestController RequestMapping(/api/auth) public class AuthController { Autowired private UserService userService; PostMapping(/login) public Result login(RequestBody LoginDTO dto) { User user userService.lambdaQuery() .eq(User::getUsername, dto.getUsername()) .one(); if (user null || !new BCryptPasswordEncoder().matches(dto.getPassword(), user.getPassword())) { return Result.fail(账号或密码错误); } String token JwtUtil.createToken(user.getId(), user.getRole()); return Result.ok(token); } }lambdaQuery()是 MyBatis-Plus 的写法等价于手写select * from user where username ?但不需要维护 XML。注意密码校验用的是BCryptPasswordEncoder.matches不是equals因为数据库里存的通常是 BCrypt 加密串这一点答辩时常常被追问。这段代码本质上把 java 基础里的字符串处理、异常处理、依赖注入都串起来了读懂了再改别的地方会顺很多。拿到 token 只是第一步真正拦数据的是拦截器Component public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token request.getHeader(Authorization); if (token ! null token.startsWith(Bearer )) { token token.substring(7); } try { Long userId JwtUtil.getUserId(token); if (userId null) { throw new RuntimeException(token无效); } request.setAttribute(userId, userId); return true; } catch (Exception e) { response.setStatus(401); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:401,\message\:\登录已过期\}); return false; } } }这段代码解决的是「前端每次请求都要把当前登录用户带过来」的问题。Bearer前缀是前后端约定很多前端封装 axios 时会在请求头里带上Authorization: Bearer token你拦截器不处理前缀就会误判。拦截器注册在WebMvcConfigurer中一般这样写Configuration public class WebConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor) .addPathPatterns(/api/**) .excludePathPatterns(/api/auth/login, /api/register, /error); } }需要放行的路径是两个登录接口和注册接口。如果项目里还配了 Spring Security逻辑会多一层过滤器链白屏概率也跟着上来。对毕设来说光是这个拦截器就足够向老师解释「如何保护接口资源」。列表分页也是必问点。你可以在配置类里加 MyBatis-Plus 分页插件Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; }这样page(new Page(current, size))就自动带上limit而不是一次性把所有数据查回来再用 Java 截断。这一点很小但能体现你理解「分页应该在数据库层做」。3.3 用接口测试工具验证最小闭环后端不要急着写前端先用 curl 或者 Postman 验证一条链路登录拿 token再带 token 查社团列表。用 curl 最直观curl -X POST http://localhost:8080/api/auth/login \ -H Content-Type: application/json \ -d {username:admin,password:123456}返回{code:200,data:eyJhbGciOiJIUzI1Ni...}就说明账号密码、数据库连接、JWT 生成全通了。如果返回 401先看密码是不是 BCrypt 加密而不是看登录接口逻辑如果返回 500看控制台有没有 SQL 异常多半是表字段和实体类对不上。拿到 token 后请求一个需要登录的接口curl -X GET http://localhost:8080/api/club/list?current1size10 \ -H Authorization: Bearer 你的token这一步能查出社团分页列表后端的最小闭环就算跑通了。做到这里再出现前端联调问题你就可以很有底气地说「接口没问题是前端或者跨域的事」。4. 前端 vue 联调与避坑跨域、请求封装和路由守卫前后端分离项目 80% 的联调问题不在业务逻辑而在请求地址和浏览器安全策略。这一章先给出一套能直接照抄的前端骨架再列我反复踩的 5 个坑每个都按「现象、原因、解决」三段式写你可以当排查手册用。4.1 先让 vue 项目跑起来安装依赖、axios 封装与后端跨域配置先确认前端目录的package.json里 scripts 字段。Vue 2 vue-cli 项目一般是npm run serveVue 3 Vite 项目是npm run dev。安装依赖时如果之前配置过慢的源可以临时指定镜像源cd club-web npm install npm run servenode-sass是你的第一个潜在敌人。老项目里node-sass对 Node 版本极其敏感安装阶段报错先别急着重装看一眼 Node 版本和package.json里node-sass的版本是否匹配。更省事的办法是把node-sass换成sassDart Sass大部分项目只需要改 package.json 和重新装依赖。前后端分离后前端地址是http://localhost:3000后端是http://localhost:8080浏览器直接跨域所以第一个要解决的是后端允许谁来访问。常见的做法是在后端加一个全局 CORS 配置类而不是在每个 controller 上写CrossOrigin后者容易漏、也不好维护。Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }allowedOriginPatterns(*)在开发环境下放开所有来源但答辩时你可以补充一句生产环境应该收敛成固定的域名。allowedMethods里必须包含OPTIONS因为浏览器跨域请求会先发一个预检请求不放开 OPTIONS 就会在 console 里看到 CORS 错。allowCredentials(true)是配合需要 cookie 的场景如果只是用 JWT其实可以不设但设了也不会影响当前接口。axios 请求封装我习惯放在src/utils/request.jsimport axios from axios const service axios.create({ baseURL: http://localhost:8080, timeout: 10000 }) service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer token } return config }) service.interceptors.response.use( response response.data, error { if (error.response error.response.status 401) { localStorage.removeItem(token) window.location.href /login } return Promise.reject(error) } ) export default servicebaseURL写成后端端口是因为后端已经用 CORS 配置放开了跨域。如果你的后端server.port改了这里同步改就行。注意不要在前端请求路径里重复拼/api我习惯是request.post(/api/auth/login)后端 controller 加上RequestMapping(/api/auth)后实际访问路径就是http://localhost:8080/api/auth/login。路由守卫是另一个必写点。社团管理系统里学生、社团管理员、团委管理员看到的菜单不同路由至少要有一个「未登录跳登录页」的全局前置守卫router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.meta.requiresAuth !token) { next(/login) } else { next() } })如果你有编辑活动、查看详情这类页面路由传参可以用{ path: /activity/edit, query: { id: row.id } }在目标组件里用this.$route.query.id拿到。这属于 vue 路由参数的基础用法也是页面上跳详情最常见的动作。做完这些前端的最小链路就是登录页调用/api/auth/login拿到 token 存 localStorage路由跳到社团列表页列表页通过封装好的 axios 请求数据。如果这一步通了剩下的都是页面渲染细节。4.2 避坑记录5 个让页面白屏或接口 404 的典型故障第一登录请求返回 404。现象是 console 里POST http://localhost:8080/api/auth/login 404后端日志没有任何打印。原因通常是前端请求路径中的/api和后端RequestMapping冲突后端接口实际是/auth/login而不是/api/auth/login或者 request.js 的 baseURL 写错端口。解决方法是先看后端控制台有没有请求进来没有就改前端 baseURL 的端口有但 404就在后端把接口前缀统一改成/api保持一致。第二接口返回 200 但页面数据是空的。现象是 Network 里响应体正常列表 table 却一行没有。原因多半是后端返回结构是{code:200, data:{records:[...]}}前端代码直接用res.data当作数组去v-for。解决方法是先在 console 打印res看 data 到底是一层还是两层然后修request.js的响应拦截器让它返回response.data在页面里再取res.data.records。第三浏览器报 CORS 错误。现象是 console 提示Access-Control-Allow-Origin、XMLHttpRequest ... has been blocked by CORS policy请求 Method 显示 OPTIONS。原因是你后端没配 CorsConfig或者allowedMethods里没有 OPTIONS。解决方法是把 4.1 的配置类加上并确认预检请求能通过。如果加了还报错看看是不是配置类没有生效比如被 Spring Security 的过滤器先拦住了。第四启动时digital envelope routines::unsupported。现象是npm run serve报error:0308010C:digital envelope routines::unsupported然后进程退出。原因是 Node 17 以上和 Webpack 4 的 OpenSSL 兼容问题Vue 2 项目特别常见。解决方法是临时设环境变量NODE_OPTIONS--openssl-legacy-provider或者在.env.development里配NODE_OPTIONS--openssl-legacy-provider。如果不想折腾直接用 Node 16少很多兼容问题。第五登录成功后刷新页面又跳回登录页。现象是 token 明明存了刷新后路由守卫还是把你踢出去。原因通常是前端把 token 存到了sessionStorage或某个 js 变量里刷新就没了还有一种情况是路由元信息没写meta: { requiresAuth: true }或者字段名写错了。解决方法是统一用localStorage.setItem存 token并且在router.beforeEach里打印to.meta检查一下别让这种基础问题影响答辩心情。这五条覆盖了我能想到的前端联调大头。如果你能把项目跑到「登录、列表、详情、审核」四个页面都通就已经超过多数只完成课程设计的同学了。顺带一提路由守卫、axios 拦截器这些点本来就是 vue 面试题中的高频内容做这个系统时理解一遍后面找实习也有的聊。5. 答辩前的验收清单从数据正确性到代码答辩点系统能跑只是及格线真正拉开分数的是「你有多少边界案例能说清楚」。我一般会在提交前留一个下午做验收不按自己熟悉的操作路径而是模拟一个陌生人来用系统。5.1 答辩前十分钟跑完的验收清单验收项操作方法预期结果三种角色登录用学生、社长、团委管理员三个账号分别登录登录后菜单和默认页面不同社长看不到团委的审核页权限绕过不登录直接访问/api/activity/approve返回 401 JSON前端跳转登录页审批闭环社长发起活动团委驳回社长修改再次提交每次操作都能在审批记录表里看到历史而不是直接覆盖状态分页与搜索在第 2 页输入关键词搜索URL 参数重新带上current1不要停留在第 2 页返回空数据一致性删除一个社团查看所属成员和活动要么逻辑删除要么外键约束报错不能出现成员还在但社团消失时间显示创建一条带具体时间的记录查看列表时间与本地时间一致不在 8 小时时区坑里这六项里权限绕过建议现场演示给老师看这是最能体现你做了安全设计的一个动作。对应代码就是第 3 章的拦截器你能回答出「为什么/api/auth/login要放行、其他接口为什么要拦截」就足够。5.2 答辩时最容易被追问的两个点老师大概率会问的第一个问题是「如果用户量多了token 过期了怎么办」。你可以答前端在响应拦截器里统一处理 401让用户重新登录而不是页面直接白屏后端把expire-hours调短并说明生产环境应该接入 Redis 做刷新 token。第二个问题是「社团和学生的多对多为什么拆一张 member 表」你就把 2.3 节那张表的关系讲一遍说明不拆会产生冗余数据。这里有一个我吃过的亏演示时用的是自己日常造的脏数据活动名称、审批意见都带着「测试」字样很掉分。所以答辩前我会用sql/club.sql重导一次数据库保证数据干净。另外一个技巧是把后端启动窗口和前端页面放在同一个屏幕老师看到你切换窗口不慌也会默认你确实是自己写的代码。做这个系统最大的收获不是 springboot 或 vue 的某个 api 记得多熟而是你会明白一个看起来简单的管理系统拆开后是角色模型、状态流转、接口安全、前端状态管理四个层面的问题。RBAC 权限模型、JWT 认证、MyBatis 分页插件这些本身就是 Java 面试里反复出现的高频点毕设做一遍面试时不至于空手。希望这份从压缩包到答辩的路径能帮到你。本文还有配套的精品资源点击获取
返回列表