1. 项目概述
作为一名经历过多次Java Web项目开发的程序员,我深知一个完整的课表管理系统对于高校教务管理的重要性。这个基于SpringBoot+Vue的课表管理系统,是我在指导毕业设计过程中总结出的一个典型范例,它完美展现了现代Web应用开发的核心技术栈。
这个系统采用前后端分离架构,后端使用SpringBoot框架提供RESTful API,前端采用Vue.js构建用户界面,数据库使用MySQL。系统实现了用户权限管理、课表查询与编辑、课程冲突检测等核心功能,完全满足高校教务管理的基本需求。
2. 技术选型与架构设计
2.1 后端技术栈
后端采用SpringBoot 2.7.x作为基础框架,这是目前Java Web开发最主流的选择。SpringBoot的自动配置特性大大简化了项目搭建过程,内嵌Tomcat服务器也让部署变得异常简单。
数据持久层使用MyBatis-Plus 3.5.x,它是对MyBatis的增强工具,提供了强大的CRUD操作和条件构造器,可以显著减少样板代码。例如,对于课程信息的查询,我们只需要这样写:
java复制// 查询周一的所有课程
LambdaQueryWrapper<Course> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Course::getWeekDay, 1);
List<Course> mondayCourses = courseMapper.selectList(queryWrapper);
安全认证采用Spring Security + JWT的方案。用户登录后,系统会生成一个JWT token返回给前端,后续请求都需要在Header中携带这个token进行鉴权。
2.2 前端技术栈
前端使用Vue 3.x作为核心框架,配合Vue Router实现路由管理,Vuex进行状态管理。UI组件库选择了Element Plus,它提供了丰富的现成组件,可以快速构建美观的界面。
前端工程使用Vite作为构建工具,相比传统的Webpack,Vite的启动速度和热更新速度都有显著提升,特别适合开发阶段的快速迭代。
2.3 数据库设计
数据库采用MySQL 8.0,主要包含三张核心表:
- 用户表(user):存储系统用户信息
- 课程表(course):存储课程基本信息
- 课表记录表(schedule):关联用户和课程
表之间的关系如下:
- 一个用户可以有多条课表记录(一对多)
- 一门课程可以被多个用户选择(多对多,通过schedule表实现)
3. 核心功能实现
3.1 用户认证与权限管理
系统采用RBAC(基于角色的访问控制)模型,定义了三种角色:
- 学生:只能查看和选择课程
- 教师:可以管理自己教授的课程
- 管理员:拥有系统所有权限
用户登录接口实现示例:
java复制@PostMapping("/login")
public Result login(@RequestBody LoginDTO loginDTO) {
// 1. 验证用户名密码
User user = userService.getByUsername(loginDTO.getUsername());
if(user == null || !passwordEncoder.matches(loginDTO.getPassword(), user.getPasswordHash())) {
return Result.error("用户名或密码错误");
}
// 2. 生成JWT token
String token = JwtUtil.generateToken(user.getUserId(), user.getRoleType());
// 3. 返回token和用户基本信息
LoginVO vo = new LoginVO();
vo.setToken(token);
vo.setUserInfo(userService.getUserInfo(user.getUserId()));
return Result.success(vo);
}
3.2 课表查询与展示
课表查询是系统的核心功能之一。前端通过调用后端API获取当前用户的课表数据,然后使用Element Plus的时间线组件进行可视化展示。
关键实现点:
- 按周次和学期过滤课程
- 支持按天/周/月三种视图切换
- 课程冲突高亮显示
课表查询接口示例:
java复制@GetMapping("/schedule")
public Result getSchedule(@RequestParam(required = false) String semester) {
// 1. 获取当前用户ID
Long userId = SecurityUtil.getCurrentUserId();
// 2. 如果没有指定学期,使用当前学期
if(semester == null) {
semester = semesterService.getCurrentSemester();
}
// 3. 查询课表
List<ScheduleVO> schedule = scheduleService.getUserSchedule(userId, semester);
return Result.success(schedule);
}
3.3 课程冲突检测
课程冲突检测是系统的亮点功能。当用户选择新课程时,系统会自动检测时间冲突。冲突检测逻辑如下:
- 检查同一时间段是否已有其他课程
- 检查同一教室是否在同一时间被占用
- 检查教师是否在同一时间有其他教学任务
冲突检测算法实现:
java复制public boolean checkCourseConflict(Long userId, Long courseId) {
// 1. 获取要添加的课程信息
Course newCourse = courseMapper.selectById(courseId);
// 2. 获取用户当前所有课程
List<Course> existingCourses = courseMapper.selectByUserId(userId);
// 3. 检查时间冲突
for(Course existing : existingCourses) {
if(existing.getWeekDay() == newCourse.getWeekDay()
&& !(existing.getEndTime().before(newCourse.getStartTime())
|| existing.getStartTime().after(newCourse.getEndTime()))) {
return true; // 存在冲突
}
}
return false; // 无冲突
}
4. 项目部署与运行
4.1 后端部署
后端项目使用Maven进行依赖管理,部署步骤如下:
- 打包项目:
bash复制mvn clean package
- 运行jar包:
bash复制java -jar target/timetable-system-1.0.0.jar
- 配置生产环境参数:
properties复制# application-prod.properties
spring.datasource.url=jdbc:mysql://localhost:3306/timetable?useSSL=false
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.profiles.active=prod
4.2 前端部署
前端项目使用Vite构建,部署步骤如下:
- 安装依赖:
bash复制npm install
- 生产环境构建:
bash复制npm run build
- 部署生成的dist目录到Nginx或Apache服务器
4.3 数据库初始化
系统提供了完整的SQL脚本,初始化步骤如下:
- 创建数据库:
sql复制CREATE DATABASE timetable CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- 执行建表脚本:
sql复制-- 用户表
CREATE TABLE user (
user_id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
password_hash VARCHAR(100) NOT NULL,
role_type TINYINT NOT NULL COMMENT '1-学生,2-教师,3-管理员',
email VARCHAR(50),
phone_number VARCHAR(20),
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 课程表
CREATE TABLE course (
course_id BIGINT PRIMARY KEY AUTO_INCREMENT,
course_name VARCHAR(50) NOT NULL,
teacher_id BIGINT NOT NULL,
classroom VARCHAR(20) NOT NULL,
start_time TIME NOT NULL,
end_time TIME NOT NULL,
week_day TINYINT NOT NULL COMMENT '1-7对应周一到周日',
FOREIGN KEY (teacher_id) REFERENCES user(user_id)
);
-- 课表记录表
CREATE TABLE schedule (
schedule_id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
course_id BIGINT NOT NULL,
semester VARCHAR(20) NOT NULL,
is_conflict BOOLEAN DEFAULT FALSE,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES user(user_id),
FOREIGN KEY (course_id) REFERENCES course(course_id)
);
5. 开发经验与技巧
5.1 前后端联调技巧
- 使用Swagger生成API文档,方便前端查阅接口规范
- 开发阶段开启CORS,避免跨域问题
- 使用Postman测试接口,确保返回数据结构正确
Swagger配置示例:
java复制@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.timetable"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("课表管理系统API文档")
.description("SpringBoot+Vue课表管理系统接口文档")
.version("1.0")
.build();
}
}
5.2 性能优化建议
- 课表查询添加Redis缓存,减少数据库压力
- 使用MyBatis二级缓存提高查询效率
- 前端使用懒加载和分页技术优化大数据量展示
Redis缓存配置示例:
java复制@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
@Service
@CacheConfig(cacheNames = "schedule")
public class ScheduleServiceImpl implements ScheduleService {
@Override
@Cacheable(key = "#userId + ':' + #semester")
public List<ScheduleVO> getUserSchedule(Long userId, String semester) {
// 数据库查询逻辑
}
}
5.3 常见问题解决
- 跨域问题:确保后端配置了正确的CORS策略
- JWT过期:前端需要实现token自动刷新机制
- 时区问题:统一使用UTC时间,避免服务器和客户端时区不一致
CORS配置示例:
java复制@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("Authorization")
.maxAge(3600);
}
}
6. 项目扩展方向
这个基础版的课表管理系统还可以进一步扩展:
- 添加教室预约功能,允许教师申请调课
- 集成日历同步,将课表导出到Google日历或Outlook
- 开发移动端APP,使用Flutter或React Native实现跨平台
- 增加数据分析模块,统计课程出勤率和教学质量
教室预约功能设计思路:
java复制public class ClassroomBooking {
private Long bookingId;
private Long classroomId;
private Long applicantId; // 申请人ID
private Date bookingDate;
private Time startTime;
private Time endTime;
private String purpose;
private Integer status; // 0-待审核,1-已批准,2-已拒绝
private String remark;
// getters and setters
}
在实际开发中,我发现很多同学容易忽视异常处理和日志记录。良好的异常处理可以大大提高系统的健壮性,而详细的日志记录则是排查问题的利器。建议在项目中统一使用Slf4j记录日志,并对所有可能出错的环节进行适当的异常捕获和处理。