1. 项目概述
这个基于SpringBoot+Vue+MySQL的社团管理系统是我在2022年完成的毕业设计项目,前后耗时3个月开发完成。系统采用前后端分离架构,实现了社团管理全流程的数字化解决方案,包括成员管理、活动管理、物资管理、审批流程等核心功能模块。项目最终获得了学院优秀毕业设计奖,并在实际部署后为学校15个社团提供了服务支持。
系统最大的特点是采用了现代化的技术栈组合:后端使用SpringBoot 2.7提供RESTful API,前端采用Vue 3 + Element Plus构建管理界面,数据库使用MySQL 8.0,并通过Redis实现会话管理和缓存优化。整套系统代码结构清晰,模块化程度高,特别适合作为计算机相关专业学生的毕业设计参考项目。
2. 系统架构设计
2.1 技术选型分析
选择SpringBoot作为后端框架主要基于以下几点考虑:
- 快速开发:自动配置和起步依赖大大减少了XML配置
- 生态丰富:整合MyBatis、Redis等组件非常方便
- 易于部署:内嵌Tomcat,打包成jar即可运行
- 社区支持:遇到问题容易找到解决方案
前端选用Vue 3的组合式API相比选项式API更适合复杂管理系统开发:
- 更好的逻辑复用能力
- 更灵活的组合方式
- 更完善的TypeScript支持
数据库选择MySQL 8.0而非5.7版本是因为:
- 支持窗口函数等高级特性
- 性能提升明显
- JSON支持更完善
2.2 系统模块划分
系统主要分为六大功能模块:
-
用户认证模块
- JWT令牌认证
- 基于RBAC的权限控制
- 密码加密存储
-
社团管理模块
- 社团CRUD操作
- 社团分类管理
- 社团招新管理
-
成员管理模块
- 成员信息维护
- 成员角色分配
- 成员考勤统计
-
活动管理模块
- 活动发布与审批
- 活动报名管理
- 活动总结提交
-
物资管理模块
- 物资入库登记
- 物资借还管理
- 物资报废处理
-
系统管理模块
- 数据字典管理
- 系统日志查询
- 个人信息设置
3. 数据库设计
3.1 核心表结构
系统共设计28张数据表,以下是部分核心表结构:
- 用户表(sys_user)
sql复制CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '登录账号',
`password` varchar(100) NOT NULL COMMENT '密码',
`salt` varchar(20) DEFAULT NULL COMMENT '盐值',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`mobile` varchar(20) DEFAULT NULL COMMENT '手机号',
`status` tinyint DEFAULT '0' COMMENT '状态 0:正常 1:停用',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`user_id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户';
- 社团表(club_info)
sql复制CREATE TABLE `club_info` (
`club_id` bigint NOT NULL AUTO_INCREMENT,
`club_name` varchar(100) NOT NULL COMMENT '社团名称',
`club_type` varchar(50) NOT NULL COMMENT '社团类型',
`founder_id` bigint NOT NULL COMMENT '创始人ID',
`create_time` datetime NOT NULL COMMENT '成立时间',
`description` text COMMENT '社团简介',
`logo_url` varchar(255) DEFAULT NULL COMMENT 'Logo地址',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '状态 0:正常 1:停用',
PRIMARY KEY (`club_id`),
KEY `idx_type` (`club_type`),
KEY `idx_founder` (`founder_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='社团信息';
- 活动表(activity_info)
sql复制CREATE TABLE `activity_info` (
`activity_id` bigint NOT NULL AUTO_INCREMENT,
`club_id` bigint NOT NULL COMMENT '所属社团',
`activity_name` varchar(200) NOT NULL COMMENT '活动名称',
`start_time` datetime NOT NULL COMMENT '开始时间',
`end_time` datetime NOT NULL COMMENT '结束时间',
`location` varchar(200) NOT NULL COMMENT '活动地点',
`max_people` int DEFAULT NULL COMMENT '人数上限',
`current_people` int DEFAULT '0' COMMENT '当前报名数',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '状态 0:待审核 1:已通过 2:已拒绝 3:已取消',
`create_time` datetime NOT NULL COMMENT '创建时间',
`create_by` bigint NOT NULL COMMENT '创建人',
PRIMARY KEY (`activity_id`),
KEY `idx_club` (`club_id`),
KEY `idx_time` (`start_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='活动信息';
3.2 索引优化策略
针对系统查询特点做了以下索引优化:
- 高频查询字段建立组合索引
- 范围查询字段单独建立索引
- 文本字段使用前缀索引
- 外键关系字段必建索引
4. 后端实现细节
4.1 SpringBoot配置
核心配置类示例:
java复制@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/test/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
4.2 业务逻辑实现
活动审批流程的核心代码:
java复制@Service
public class ActivityServiceImpl implements ActivityService {
@Autowired
private ActivityMapper activityMapper;
@Autowired
private NotificationService notificationService;
@Transactional
@Override
public void approveActivity(Long activityId, Long userId, boolean approved, String comment) {
Activity activity = activityMapper.selectById(activityId);
if (activity == null) {
throw new BusinessException("活动不存在");
}
if (activity.getStatus() != ActivityStatus.PENDING.getValue()) {
throw new BusinessException("活动当前状态不可审批");
}
activity.setStatus(approved ? ActivityStatus.APPROVED.getValue() : ActivityStatus.REJECTED.getValue());
activity.setReviewerId(userId);
activity.setReviewComment(comment);
activity.setReviewTime(new Date());
activityMapper.updateById(activity);
// 发送通知
String message = approved ? "您的活动申请已通过" : "您的活动申请被拒绝,原因:" + comment;
notificationService.sendNotification(
activity.getCreateBy(),
"活动审批结果",
message,
NotificationType.SYSTEM
);
}
}
5. 前端实现细节
5.1 Vue组件设计
活动列表组件关键代码:
vue复制<template>
<div class="activity-container">
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="activityName" label="活动名称" width="180" />
<el-table-column prop="clubName" label="所属社团" width="120" />
<el-table-column prop="startTime" label="开始时间" width="180">
<template #default="scope">
{{ formatDate(scope.row.startTime) }}
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template #default="scope">
<el-tag :type="statusType(scope.row.status)">
{{ statusText(scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template #default="scope">
<el-button size="small" @click="handleView(scope.row)">详情</el-button>
<el-button
size="small"
type="primary"
v-if="hasPermission('activity:approve') && scope.row.status === 0"
@click="handleApprove(scope.row)"
>
审批
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { getActivityList } from '@/api/activity'
import { formatDate } from '@/utils/date'
import { usePermission } from '@/hooks/usePermission'
const { hasPermission } = usePermission()
const tableData = ref([])
const statusType = (status) => {
const types = ['info', 'success', 'danger', 'warning']
return types[status] || ''
}
const statusText = (status) => {
const texts = ['待审核', '已通过', '已拒绝', '已取消']
return texts[status] || ''
}
const fetchData = async () => {
try {
const res = await getActivityList()
tableData.value = res.data
} catch (err) {
console.error(err)
}
}
onMounted(() => {
fetchData()
})
</script>
5.2 状态管理
使用Pinia进行全局状态管理:
javascript复制// stores/user.js
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
token: localStorage.getItem('token') || '',
userInfo: JSON.parse(localStorage.getItem('userInfo')) || null,
permissions: JSON.parse(localStorage.getItem('permissions')) || []
}),
actions: {
setToken(token) {
this.token = token
localStorage.setItem('token', token)
},
setUserInfo(userInfo) {
this.userInfo = userInfo
localStorage.setItem('userInfo', JSON.stringify(userInfo))
},
setPermissions(permissions) {
this.permissions = permissions
localStorage.setItem('permissions', JSON.stringify(permissions))
},
logout() {
this.token = ''
this.userInfo = null
this.permissions = []
localStorage.removeItem('token')
localStorage.removeItem('userInfo')
localStorage.removeItem('permissions')
}
},
getters: {
isLogin: (state) => !!state.token,
hasPermission: (state) => (permission) => {
return state.permissions.includes(permission)
}
}
})
6. 系统部署方案
6.1 环境准备
生产环境推荐配置:
- 服务器:2核4G云服务器(学生优惠机型即可)
- 操作系统:CentOS 7.9
- JDK:1.8+
- Node.js:16.x
- MySQL:8.0
- Redis:6.x
- Nginx:1.20+
6.2 部署步骤
后端部署流程:
- 打包SpringBoot应用
bash复制mvn clean package -DskipTests
- 上传jar包到服务器
- 创建启动脚本start.sh
bash复制#!/bin/bash
nohup java -jar club-management.jar --spring.profiles.active=prod > app.log 2>&1 &
- 设置开机自启
bash复制sudo chmod +x start.sh
sudo ln -s /path/to/start.sh /etc/init.d/club-management
前端部署流程:
- 构建生产环境代码
bash复制npm run build
- 配置Nginx
nginx复制server {
listen 80;
server_name yourdomain.com;
location / {
root /path/to/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
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;
}
}
7. 项目文档编写
7.1 论文结构建议
毕业设计论文建议包含以下章节:
-
绪论
- 研究背景与意义
- 国内外研究现状
- 论文组织结构
-
系统需求分析
- 功能性需求
- 非功能性需求
- 用例分析
-
系统设计
- 架构设计
- 功能模块设计
- 数据库设计
-
系统实现
- 关键技术实现
- 核心功能展示
- 系统测试方案
-
总结与展望
- 工作总结
- 不足与改进
7.2 部署文档要点
完整的部署文档应包含:
-
环境要求
- 硬件配置
- 软件依赖
-
数据库配置
- 初始化脚本
- 基础数据导入
-
后端部署
- 打包说明
- 启动参数
- 日志配置
-
前端部署
- 环境变量配置
- 构建命令
- Nginx配置
-
常见问题
- 端口冲突解决
- 跨域问题处理
- 性能调优建议
8. 开发经验总结
8.1 技术难点攻克
-
文件上传下载方案优化:
- 最初使用本地存储,后改为MinIO对象存储
- 实现分片上传和断点续传
- 添加MD5校验保证文件完整性
-
复杂审批流程实现:
- 使用状态机模式管理流程状态
- 设计可配置的审批规则
- 实现审批链和会签功能
-
大数据量导出性能优化:
- 采用分页查询+流式写入
- 使用多线程加速处理
- 添加进度提示和取消功能
8.2 项目改进方向
- 移动端适配:开发微信小程序版本
- 数据分析:增加社团活跃度分析看板
- 消息推送:集成WebSocket实时通知
- 微服务改造:按功能模块拆分服务
这套系统从技术选型到最终部署,完整覆盖了企业级应用开发的各个环节。作为毕业设计项目,它不仅满足了学术要求,更具备了实际应用价值。项目代码规范、文档齐全,特别适合作为计算机专业学生学习和参考的范例。