# campus-sports-booking **Repository Path**: moustwo/campus-sports-booking ## Basic Information - **Project Name**: campus-sports-booking - **Description**: 校园体育场馆预约系统是一个面向高校师生的综合性体育场馆预约管理平台,采用前后端分离架构,支持Web管理端和微信小程序双端访问。系统实现了用户管理、场馆管理、预约管理等核心功能,为校园体育资源的高效利用提供了完整的解决方案。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 5 - **Forks**: 0 - **Created**: 2025-10-11 - **Last Updated**: 2026-03-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 校园体育场馆预约系统技术文档 ## 项目概述 校园体育场馆预约系统是一个面向高校师生的综合性体育场馆预约管理平台,采用前后端分离架构,支持Web管理端和微信小程序双端访问。系统实现了用户管理、场馆管理、预约管理等核心功能,为校园体育资源的高效利用提供了完整的解决方案。 ### 项目特点 - **多端支持**: Web管理端 + 微信小程序 - **多角色权限**: 学生、教师、管理员三级权限体系 - **现代化技术栈**: Spring Boot 3 + Vue 3 + 微信小程序 - **高性能缓存**: Redis分布式缓存 - **安全认证**: Sa-Token权限框架 ## 技术架构 ### 整体架构图 ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Web前端 │ │ 微信小程序 │ │ 官网展示 │ │ Vue 3 │ │ 原生开发 │ │ 静态页面 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └───────────────────────┼───────────────────────┘ │ ┌─────────────────┐ │ 后端API服务 │ │ Spring Boot │ └─────────────────┘ │ ┌─────────────────┐ │ 数据存储层 │ │ MySQL + Redis │ └─────────────────┘ ``` ### 技术栈详情 #### 后端技术栈 - **框架**: Spring Boot 3.2.0 - **Java版本**: Java 17 - **数据库**: MySQL 8.0 - **缓存**: Redis 6.x - **ORM**: Spring Data JPA + Hibernate - **认证**: Sa-Token 1.44.0 - **构建工具**: Maven - **API文档**: 内置接口文档 #### 前端技术栈 - **框架**: Vue 3 (Composition API) - **构建工具**: Vite 5.4.10 - **状态管理**: Pinia + 持久化插件 - **路由**: Vue Router 4 - **HTTP客户端**: Axios 1.10.0 - **UI组件**: 自定义组件库 #### 小程序技术栈 - **开发方式**: 微信小程序原生开发 - **开发工具**: 微信开发者工具 - **API调用**: wx.request封装 - **状态管理**: 全局数据管理 ## 项目结构 ### 后端项目结构 ``` campus-sports-booking-backend/ ├── src/main/java/com/campus/ │ ├── config/ # 配置类 │ │ ├── SaTokenConfig.java # Sa-Token配置 │ │ ├── RedisConfig.java # Redis配置 │ │ ├── SecurityConfig.java # 安全配置 │ │ └── WebConfig.java # Web配置 │ ├── controller/ # 控制器层 │ │ ├── AuthController.java # 认证控制器 │ │ ├── UserController.java # 用户管理 │ │ ├── VenueController.java # 场馆管理 │ │ └── BookingController.java # 预约管理 │ ├── service/ # 业务逻辑层 │ │ ├── UserService.java # 用户服务 │ │ ├── VenueService.java # 场馆服务 │ │ └── ReservationService.java # 预约服务 │ ├── repository/ # 数据访问层 │ │ ├── UserRepository.java # 用户数据访问 │ │ ├── VenueRepository.java # 场馆数据访问 │ │ └── ReservationRepository.java # 预约数据访问 │ ├── entity/ # 实体类 │ │ ├── User.java # 用户实体 │ │ ├── Venue.java # 场馆实体 │ │ └── Reservation.java # 预约实体 │ ├── dto/ # 数据传输对象 │ │ ├── LoginRequest.java # 登录请求 │ │ ├── LoginResponse.java # 登录响应 │ │ └── ApiResponse.java # 统一响应格式 │ └── util/ # 工具类 │ ├── SaTokenUtil.java # Sa-Token工具 │ └── JwtUtil.java # JWT工具(已弃用) ├── src/main/resources/ │ └── application.yml # 应用配置文件 ├── db/ │ └── stadiumreservationdb.sql # 数据库脚本 └── pom.xml # Maven配置 ``` ### 前端项目结构 ``` campus-sports-booking-frontend/ ├── src/ │ ├── api/ # API接口 │ │ ├── request.js # 请求封装 │ │ ├── user.js # 用户API │ │ └── booking.js # 预约API │ ├── components/ # 组件 │ │ ├── common/ # 通用组件 │ │ ├── layout/ # 布局组件 │ │ └── venue/ # 场馆组件 │ ├── views/ # 页面视图 │ │ ├── Login.vue # 登录页 │ │ ├── Dashboard.vue # 仪表板 │ │ ├── VenueManagement.vue # 场馆管理 │ │ └── BookingManagement.vue # 预约管理 │ ├── stores/ # 状态管理 │ │ ├── user.js # 用户状态 │ │ ├── booking.js # 预约状态 │ │ └── system.js # 系统状态 │ ├── router/ # 路由配置 │ │ └── index.js # 路由定义 │ ├── layout/ # 布局 │ │ └── Layout.vue # 主布局 │ └── assets/ # 静态资源 ├── public/ # 公共资源 └── package.json # 依赖配置 ``` ### 小程序项目结构 ``` campus-sports-booking-miniprogram/ ├── pages/ # 页面 │ ├── index/ # 首页 │ ├── login/ # 登录页 │ ├── venues/ # 场馆列表 │ ├── venue-detail/ # 场馆详情 │ ├── booking/ # 预约页面 │ ├── my-bookings/ # 我的预约 │ └── profile/ # 个人中心 ├── utils/ # 工具类 │ ├── api.js # API封装 │ └── util.js # 通用工具 ├── app.js # 应用入口 ├── app.json # 应用配置 └── project.config.json # 项目配置 ``` ## 数据库设计 ### 数据库表结构 #### 用户表 (user) ```sql CREATE TABLE `user` ( `user_id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(100) NOT NULL COMMENT '用户名', `password` varchar(255) NOT NULL COMMENT '用户密码', `name` varchar(100) COMMENT '真实姓名', `email` varchar(100) COMMENT '用户邮箱', `phone` varchar(20) COMMENT '联系电话', `student_id` varchar(50) COMMENT '学号', `teacher_id` varchar(50) COMMENT '工号', `college` varchar(100) COMMENT '学院', `major` varchar(100) COMMENT '专业', `department` varchar(100) COMMENT '部门', `bio` varchar(500) COMMENT '个人简介', `type_id` int(11) COMMENT '用户类型ID', `status` int(11) DEFAULT 1 COMMENT '状态(1:正常,0:禁用,2:待审核)', `register_time` timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`user_id`) ); ``` #### 用户类型表 (usertype) ```sql CREATE TABLE `usertype` ( `type_id` int(11) NOT NULL COMMENT '用户类型ID', `type_name` varchar(50) COMMENT '用户类型名称', PRIMARY KEY (`type_id`) ); INSERT INTO `usertype` VALUES (1, '学生'), (2, '教师'), (3, '管理员'); ``` #### 场馆表 (venue) ```sql CREATE TABLE `venue` ( `venue_id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL COMMENT '场馆名称', `location` varchar(200) COMMENT '场馆位置', `facility` text COMMENT '场馆设施描述', `open_time` time COMMENT '开放时间', `close_time` time COMMENT '关闭时间', `image_url` varchar(500) COMMENT '场馆图片URL', PRIMARY KEY (`venue_id`) ); ``` #### 预约表 (reservation) ```sql CREATE TABLE `reservation` ( `reservation_id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) COMMENT '预约用户ID', `venue_id` int(11) COMMENT '预约场馆ID', `reservation_date` date COMMENT '预约日期', `start_time` time COMMENT '开始时间', `end_time` time COMMENT '结束时间', `status` varchar(20) DEFAULT '待审核' COMMENT '预约状态', `purpose` varchar(100) COMMENT '预约目的', `participants` int(11) DEFAULT 1 COMMENT '参与人数', `price` decimal(10,2) COMMENT '预约费用', `notes` text COMMENT '备注', `contact_name` varchar(50) COMMENT '联系人姓名', `contact_phone` varchar(20) COMMENT '联系电话', `id_number` varchar(50) COMMENT '身份证号', `emergency_contact` varchar(50) COMMENT '紧急联系人', `emergency_phone` varchar(20) COMMENT '紧急联系电话', `need_equipment` tinyint(1) DEFAULT 0 COMMENT '需要器材', `need_coach` tinyint(1) DEFAULT 0 COMMENT '需要教练', `need_lighting` tinyint(1) DEFAULT 0 COMMENT '需要照明', `equipment_details` text COMMENT '器材详情', `agree_terms` tinyint(1) DEFAULT 0 COMMENT '同意条款', `health_declaration` tinyint(1) DEFAULT 0 COMMENT '健康声明', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `confirmed_at` datetime COMMENT '确认时间', `cancelled_at` datetime COMMENT '取消时间', `completed_at` datetime COMMENT '完成时间', PRIMARY KEY (`reservation_id`) ); ``` ### 数据库关系图 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ usertype │ │ user │ │ reservation │ │ │ │ │ │ │ │ type_id(PK) │◄───┤ type_id(FK) │ │ user_id(FK) │◄──┐ │ type_name │ │ user_id(PK) │◄───┤ │ │ └─────────────┘ │ username │ │ venue_id(FK)│◄──┼──┐ │ password │ │ start_time │ │ │ │ email │ │ end_time │ │ │ │ ... │ │ status │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ ┌─────────────┐ │ │ │ venue │ │ │ │ │ │ │ │ venue_id(PK)│◄─────────────────────┘ │ │ name │ │ │ location │ │ │ facility │ │ │ open_time │ │ │ close_time │ │ └─────────────┘ │ │ ┌─────────────┐ │ │ course │ │ │ │ │ │ course_id │ │ │ teacher_id │◄────────────────────────┘ │ venue_id │ │ course_date │ └─────────────┘ ``` ## 核心功能模块 ### 1. 用户认证与授权 #### Sa-Token认证框架 系统采用Sa-Token作为权限认证框架,替代了原有的JWT方案。 **配置特点:** - Token有效期: 30天 - 支持并发登录 - Redis分布式会话 - 灵活的权限控制 **认证流程:** ```java // 登录 @PostMapping("/login") public ApiResponse login(@RequestBody LoginRequest request) { LoginResponse response = userService.loginWithSaToken(request); StpUtil.login(request.getUsername()); response.setToken(StpUtil.getTokenValue()); return ApiResponse.success("登录成功", response); } // 权限拦截 registry.addInterceptor(new SaInterceptor(handler -> { SaRouter.match("/**") .notMatch("/auth/login") .notMatch("/auth/register/**") .check(r -> StpUtil.checkLogin()); })); ``` #### 权限体系 - **学生 (type_id=1)**: 场馆预约、个人信息管理 - **教师 (type_id=2)**: 场馆预约、课程管理、学生预约审核 - **管理员 (type_id=3)**: 系统全部功能 ### 2. 场馆管理 #### 场馆信息管理 - 场馆基本信息维护 - 开放时间设置 - 设施描述管理 - 场馆图片上传 #### 场馆预约时间管理 - 时间段划分 - 可预约时间配置 - 节假日特殊安排 ### 3. 预约管理 #### 预约流程 ``` 用户选择场馆 → 选择时间 → 填写预约信息 → 提交预约 → 等待审核 → 预约确认/拒绝 ``` #### 预约状态管理 - **待审核**: 用户提交预约后的初始状态 - **已确认**: 管理员审核通过 - **已取消**: 用户主动取消或管理员拒绝 - **已完成**: 预约时间结束后自动更新 #### 预约冲突检测 ```java // 检查时间冲突 public boolean checkTimeConflict(Integer venueId, LocalDate date, LocalTime startTime, LocalTime endTime) { List conflicts = reservationRepository .findConflictingReservations(venueId, date, startTime, endTime); return !conflicts.isEmpty(); } ``` ### 4. 缓存策略 #### Redis缓存配置 ```yaml spring: cache: type: redis redis: time-to-live: 600000 # 10分钟 cache-null-values: false data: redis: host: localhost port: 6379 timeout: 2000ms ``` #### 缓存使用场景 - 用户信息缓存 - 场馆列表缓存 - 热门预约数据缓存 - 系统配置缓存 ## API接口设计 ### 统一响应格式 ```java public class ApiResponse { private boolean success; private String message; private T data; private long timestamp; } ``` ### 主要接口列表 #### 认证接口 ``` POST /auth/login # 用户登录 POST /auth/logout # 用户登出 POST /auth/register/student # 学生注册 POST /auth/register/teacher # 教师注册申请 ``` #### 用户管理接口 ``` GET /user/profile # 获取个人资料 PUT /user/profile # 更新个人资料 POST /user/change-password # 修改密码 GET /user/list # 获取用户列表(管理员) PUT /user/{id}/status # 更新用户状态(管理员) ``` #### 场馆管理接口 ``` GET /venue/list # 获取场馆列表 GET /venue/{id} # 获取场馆详情 POST /venue # 创建场馆(管理员) PUT /venue/{id} # 更新场馆(管理员) DELETE /venue/{id} # 删除场馆(管理员) ``` #### 预约管理接口 ``` GET /booking/list # 获取预约列表 GET /booking/{id} # 获取预约详情 POST /booking # 创建预约 PUT /booking/{id}/status # 更新预约状态 DELETE /booking/{id} # 取消预约 GET /booking/my # 获取我的预约 ``` ### 接口认证 所有需要认证的接口都需要在请求头中携带token: ``` satoken: {token_value} 或 Authorization: Bearer {token_value} ``` ## 前端架构设计 ### Vue 3 Composition API 采用Vue 3的Composition API进行开发,提供更好的逻辑复用和类型推导。 ```javascript // 用户状态管理示例 export const useUserStore = defineStore('user', () => { const token = ref('') const userInfo = ref({}) const isLoggedIn = ref(false) const loginAction = async (loginForm) => { const response = await login(loginForm) token.value = response.data.token userInfo.value = response.data.user isLoggedIn.value = true } return { token, userInfo, isLoggedIn, loginAction } }) ``` ### 状态管理 (Pinia) 使用Pinia进行状态管理,支持数据持久化: ```javascript // 持久化配置 { persist: { key: 'campus-booking-user-store', storage: localStorage, paths: ['token', 'userInfo', 'isLoggedIn', 'role'] } } ``` ### 路由权限控制 基于用户角色的路由权限控制: ```javascript { path: 'venue-management', component: VenueManagement, meta: { title: '场馆管理', roles: ['admin'] } } ``` ### HTTP请求封装 统一的HTTP请求处理: ```javascript // 请求拦截器 request.interceptors.request.use(config => { const userStore = useUserStore() if (userStore.token) { config.headers.satoken = userStore.token config.headers.Authorization = `Bearer ${userStore.token}` } return config }) // 响应拦截器 request.interceptors.response.use( response => { const { success, message, data } = response.data if (success) { return { data, message } } else { return Promise.reject(new Error(message)) } }, error => { // 统一错误处理 if (error.response?.status === 401) { userStore.logoutAction() window.location.href = '/login' } return Promise.reject(error) } ) ``` ## 微信小程序开发 ### 小程序架构 采用微信小程序原生开发,保证最佳的用户体验和性能。 ### 全局状态管理 ```javascript // app.js App({ globalData: { userInfo: null, token: null, baseUrl: 'http://localhost:8080', isLogin: false, userRole: null }, setLoginData(token, userInfo) { this.globalData.token = token this.globalData.userInfo = userInfo this.globalData.isLogin = true wx.setStorageSync('token', token) wx.setStorageSync('userInfo', userInfo) } }) ``` ### API封装 ```javascript // utils/api.js const request = (url, options = {}) => { const app = getApp() return new Promise((resolve, reject) => { wx.request({ url: `${app.globalData.baseUrl}${url}`, header: { 'Content-Type': 'application/json', 'satoken': app.globalData.token || '' }, ...options, success: (res) => { if (res.data.success) { resolve(res.data) } else { reject(new Error(res.data.message)) } }, fail: reject }) }) } ``` ### 页面生命周期 ```javascript Page({ data: { venues: [], loading: true }, onLoad() { this.loadVenues() }, onPullDownRefresh() { this.loadVenues().finally(() => { wx.stopPullDownRefresh() }) } }) ``` ## 部署配置 ### 开发环境配置 #### 后端配置 ```yaml # application.yml server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/stadiumreservationdb username: root password: root data: redis: host: localhost port: 6379 sa-token: token-name: satoken timeout: 2592000 is-log: true ``` #### 前端配置 ```javascript // vite.config.js export default defineConfig({ plugins: [vue()], server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } } }) ``` ### 生产环境部署 #### Docker部署 ```dockerfile # Dockerfile (后端) FROM openjdk:17-jdk-slim COPY target/sports-booking-backend-1.0.0.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app.jar"] ``` ```dockerfile # Dockerfile (前端) FROM nginx:alpine COPY dist/ /usr/share/nginx/html/ COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 80 ``` #### Docker Compose ```yaml version: '3.8' services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: stadiumreservationdb ports: - "3306:3306" redis: image: redis:6-alpine ports: - "6379:6379" backend: build: ./campus-sports-booking-backend ports: - "8080:8080" depends_on: - mysql - redis frontend: build: ./campus-sports-booking-frontend ports: - "80:80" depends_on: - backend ``` ## 安全性设计 ### 认证安全 - Sa-Token框架提供安全的会话管理 - Token自动续期机制 - 支持单点登录和踢人下线 - Redis存储会话信息,支持分布式部署 ### 数据安全 - 密码明文存储(开发环境,生产环境需加密) - SQL注入防护(JPA自动处理) - XSS攻击防护 - CSRF攻击防护 ### 接口安全 - 统一的权限拦截器 - 基于角色的访问控制 - 请求频率限制 - 敏感操作日志记录 ### 数据传输安全 - HTTPS加密传输(生产环境) - 敏感数据脱敏 - 文件上传安全检查 ## 性能优化 ### 后端优化 - **数据库优化**: - 合理的索引设计 - 分页查询避免全表扫描 - 连接池配置优化 - **缓存策略**: - Redis缓存热点数据 - 多级缓存架构 - 缓存更新策略 - **JVM优化**: - 合理的堆内存配置 - GC参数调优 - 连接池参数优化 ### 前端优化 - **构建优化**: - Vite快速构建 - 代码分割和懒加载 - 静态资源压缩 - **运行时优化**: - Vue 3性能提升 - 组件缓存 - 虚拟滚动 ### 小程序优化 - **包体积优化**: - 代码分包 - 图片压缩 - 无用代码清理 - **性能优化**: - 数据预加载 - 图片懒加载 - 请求合并 ## 监控与日志 ### 应用监控 - Spring Boot Actuator健康检查 - 自定义业务指标监控 - 系统资源监控 ### 日志管理 ```yaml logging: level: com.campus: DEBUG org.springframework.security: DEBUG pattern: console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" file: name: logs/campus-booking.log ``` ### 错误处理 ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ApiResponse handleException(Exception e) { log.error("系统异常", e); return ApiResponse.error("系统异常,请稍后重试"); } @ExceptionHandler(NotLoginException.class) public ApiResponse handleNotLoginException(NotLoginException e) { return ApiResponse.error("请先登录"); } } ``` ## 测试策略 ### 单元测试 ```java @SpringBootTest class UserServiceTest { @Autowired private UserService userService; @Test void testLogin() { LoginRequest request = new LoginRequest("admin", "123456"); LoginResponse response = userService.loginWithSaToken(request); assertNotNull(response.getToken()); } } ``` ### 集成测试 ```java @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureTestDatabase class AuthControllerTest { @Autowired private TestRestTemplate restTemplate; @Test void testLogin() { LoginRequest request = new LoginRequest("admin", "123456"); ResponseEntity response = restTemplate.postForEntity( "/auth/login", request, ApiResponse.class); assertEquals(HttpStatus.OK, response.getStatusCode()); } } ``` ### 前端测试 ```javascript // 使用Vitest进行单元测试 import { describe, it, expect } from 'vitest' import { useUserStore } from '@/stores/user' describe('UserStore', () => { it('should login successfully', async () => { const userStore = useUserStore() const result = await userStore.loginAction({ username: 'admin', password: '123456' }) expect(result.success).toBe(true) }) }) ``` ## 项目扩展性 ### 微服务架构演进 当前单体架构可以逐步演进为微服务架构: - 用户服务 - 场馆服务 - 预约服务 - 通知服务 ### 功能扩展 - 支付集成 - 消息推送 - 数据分析 - 移动端APP - 第三方系统集成 ### 技术栈升级 - Spring Boot 3.x新特性 - Vue 3.x生态完善 - 云原生部署 - 容器化编排 ## 常见问题与解决方案 ### 1. Sa-Token集成问题 **问题**: Sa-Token上下文未初始化 **解决**: 在拦截器中添加异常处理,跳过未初始化的检查 ### 2. 跨域问题 **问题**: 前端请求后端接口跨域 **解决**: 配置CORS允许的源地址和请求方法 ### 3. 缓存一致性 **问题**: Redis缓存与数据库数据不一致 **解决**: 实现缓存更新策略,在数据变更时及时清除相关缓存 ### 4. 预约冲突 **问题**: 并发预约导致时间冲突 **解决**: 数据库层面添加唯一约束,业务层面加锁处理 ### 5. 小程序授权 **问题**: 小程序用户授权和登录流程 **解决**: 实现微信授权登录,与系统用户体系打通 OBOBOB ## 总结 OBOBOB OBOBOB校园体育场馆预约系统采用现代化的技术栈和架构设计,实现了完整的场馆预约管理功能。系统具有以下特点: OBOBOB1. **技术先进**: 采用Spring Boot 3、Vue 3、Sa-Token等最新技术 2. **架构清晰**: 前后端分离,职责明确,易于维护 OBOBOB3. **功能完整**: 覆盖用户管理、场馆管理、预约管理等核心业务 4. **多端支持**: Web管理端和微信小程序双端支持 5. **安全可靠**: 完善的权限控制和安全防护机制 OBOBOB6. **性能优秀**: Redis缓存、数据库优化等性能提升措施 OBOBOB7. **扩展性强**: 模块化设计,便于功能扩展和技术升级 OBOBOB该系统为校园体育资源的数字化管理提供了完整的解决方案,提升了师生的使用体验和管理效率。