以下是基于Spring Boot + Vue的社团服务系统实现方案,包含技术选型、系统设计和核心实现思路:
一、系统架构设计
前后端分离架构:
前端(Vue3) <-- RESTful API --> 后端(Spring Boot) <--> MySQL
↑
|
文件存储(MinIO)
二、技术选型
模块 | 技术栈 |
---|---|
前端 | Vue3 + TypeScript + Pinia + Element Plus + Vue Router + Axios |
后端 | Spring Boot 3.x + MyBatis Plus + Spring Security + JWT + Lombok |
数据库 | MySQL 8.x + Redis(缓存) |
文件存储 | MinIO(替代OSS) |
其他工具 | Hutool工具库 + Swagger3 + MapStruct |
三、功能模块设计
graph TD
A[用户模块] --> A1[注册登录]
A --> A2[角色管理]
B[社团管理] --> B1[创建/解散社团]
B --> B2[成员管理]
B --> B3[申请审核]
C[活动管理] --> C1[发布活动]
C --> C2[报名管理]
C --> C3[签到管理]
D[通知中心] --> D1[站内信]
D --> D2[邮件通知]
E[论坛模块] --> E1[帖子发布]
E --> E2[评论互动]
四、数据库设计(核心表)
- 用户表(user)
CREATE TABLE `user` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`username` VARCHAR(50) UNIQUE NOT NULL,
`password` VARCHAR(100) NOT NULL,
`email` VARCHAR(100),
`role` ENUM('STUDENT', 'CLUB_ADMIN', 'SUPER_ADMIN') DEFAULT 'STUDENT'
);
- 社团表(club)
CREATE TABLE `club` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(100) NOT NULL,
`description` TEXT,
`logo_url` VARCHAR(255),
`creator_id` BIGINT NOT NULL,
`status` TINYINT DEFAULT 1 COMMENT '0-已解散 1-正常'
);
- 活动表(activity)
CREATE TABLE `activity` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`title` VARCHAR(200) NOT NULL,
`content` TEXT NOT NULL,
`club_id` BIGINT NOT NULL,
`start_time` DATETIME NOT NULL,
`location` VARCHAR(200) NOT NULL,
`max_participants` INT DEFAULT 0
);
五、接口设计示例
- 社团相关接口:
@RestController
@RequestMapping("/api/clubs")
public class ClubController {
// 创建社团
@PostMapping
@PreAuthorize("hasRole('STUDENT')")
public Result<ClubVO> createClub(@RequestBody ClubDTO dto) {
// 业务逻辑
}
// 分页查询社团列表
@GetMapping
public PageResult<ClubVO> getClubs(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size) {
// 分页查询
}
}
六、核心功能实现
1. 权限控制(Spring Security + JWT)
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/admin/**").hasRole("SUPER_ADMIN")
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
2. 文件上传(MinIO集成)
@Service
public class FileService {
@Autowired
private MinioClient minioClient;
public String uploadFile(MultipartFile file) {
String objectName = UUID.randomUUID() + "-" + file.getOriginalFilename();
minioClient.putObject(
PutObjectArgs.builder()
.bucket("club-bucket")
.object(objectName)
.stream(file.getInputStream(), file.getSize(), -1)
.build()
);
return minioConfig.getEndpoint() + "/" + objectName;
}
}
3. 活动报名(Redis分布式锁)
public class ActivityService {
public boolean signUp(Long activityId, Long userId) {
String lockKey = "activity_lock:" + activityId;
try {
// 获取分布式锁
Boolean locked = redisTemplate.opsForValue()
.setIfAbsent(lockKey, "locked", 10, TimeUnit.SECONDS);
if (Boolean.TRUE.equals(locked)) {
// 检查名额是否已满
// 创建报名记录
return true;
}
throw new RuntimeException("操作过于频繁");
} finally {
redisTemplate.delete(lockKey);
}
}
}
七、前端关键实现
- 路由守卫(权限控制)
router.beforeEach((to, from, next) => {
const authStore = useAuthStore();
if (to.meta.requiresAuth && !authStore.isAuthenticated) {
next({ name: 'Login' });
} else if (to.meta.roles && !to.meta.roles.includes(authStore.user.role)) {
next({ name: 'Forbidden' });
} else {
next();
}
});
- 社团列表页(Vue3 + Composition API)
<script setup>
import { ref, onMounted } from 'vue';
import { getClubs } from '@/api/club';
const clubs = ref([]);
const loading = ref(true);
onMounted(async () => {
try {
const res = await getClubs({ page: 1, size: 10 });
clubs.value = res.data;
} finally {
loading.value = false;
}
});
</script>
八、部署方案
- 后端:打包为可执行JAR,使用Docker部署
FROM openjdk:17
COPY target/club-service.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
- 前端:Nginx部署
server {
listen 80;
server_name example.com;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
}
}
九、扩展优化方向
- 实时通知:集成WebSocket实现活动状态变更实时推送
- 数据分析:使用Elasticsearch实现活动搜索,生成可视化报表
- 移动端适配:开发Uni-app版本覆盖小程序生态
- 安全增强:添加接口限流、敏感操作二次验证
建议开发时采用模块化开发策略,先实现核心功能再逐步扩展,使用Swagger进行接口调试,结合Jenkins实现CI/CD自动化部署。