1. 毕业设计管理系统全栈开发实战
作为一名经历过多次毕业设计指导的开发者,我深知学生在毕设管理环节面临的痛点。传统的Excel表格和邮件往来方式效率低下,师生沟通不畅,进度难以把控。这套基于SpringBoot的毕业设计管理系统,正是为了解决这些实际问题而设计的全栈解决方案。
系统采用经典的三层架构(表现层、业务逻辑层、数据访问层),前端使用Thymeleaf模板引擎配合Bootstrap实现响应式布局,后端基于SpringBoot 2.7.x构建,数据库选用MySQL 8.0。特别针对毕业设计管理的特殊需求,我们设计了课题申报、双向选择、过程管理、文档评审等核心模块,下面将详细介绍各环节的实现方案。
提示:本系统已在实际教学环境中运行两个学期,处理了300+毕业设计项目,验证了其稳定性和实用性。文末可获取完整项目资源包。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境与工具链配置
2.1 基础开发环境搭建
开发环境配置是项目启动的第一步,也是许多初学者容易踩坑的环节。推荐使用以下组合:
- JDK 17(LTS版本,兼容性最佳)
- IntelliJ IDEA 2023.2(社区版即可)
- Maven 3.8.6(注意配置阿里云镜像)
- MySQL 8.0.33(建议使用Docker部署)
bash复制# MySQL Docker快速启动命令
docker run --name grad-mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:8.0.33 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
2.2 关键依赖项配置
pom.xml中需要特别注意的依赖项包括:
xml复制<!-- SpringBoot Starter全家桶 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2.3 容易忽略的配置细节
application.yml中有几个关键配置项需要特别注意:
yaml复制spring:
thymeleaf:
cache: false # 开发阶段关闭缓存
encoding: UTF-8
mode: HTML
datasource:
url: jdbc:mysql://localhost:3306/graduation?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 显示SQL日志
global-config:
db-config:
logic-delete-field: deleted # 逻辑删除字段
logic-delete-value: 1
logic-not-delete-value: 0
3. 数据库设计与核心表结构
3.1 数据库ER图设计
系统主要包含以下核心表:
- 用户表(sys_user):存储师生信息
- 课题表(topic):毕业设计课题信息
- 选题记录(selection_record):学生选题结果
- 进度记录(progress):周志/月报记录
- 文档表(document):论文/开题报告等
- 评审表(review):教师评审意见

3.2 关键表结构实现
用户表设计示例(包含角色权限控制):
sql复制CREATE TABLE `sys_user` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`username` varchar(50) NOT NULL COMMENT '学号/工号',
`password` varchar(100) NOT NULL COMMENT '密码(BCrypt加密)',
`real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
`role_type` tinyint NOT NULL COMMENT '角色(1管理员 2教师 3学生)',
`college` varchar(100) DEFAULT NULL COMMENT '学院',
`major` varchar(100) DEFAULT NULL COMMENT '专业',
`class_name` varchar(50) DEFAULT NULL COMMENT '班级(学生专用)',
`title` varchar(50) DEFAULT NULL COMMENT '职称(教师专用)',
`deleted` tinyint DEFAULT '0' COMMENT '逻辑删除',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
课题表设计特别注意状态流转:
sql复制CREATE TABLE `topic` (
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL COMMENT '课题名称',
`description` text COMMENT '课题描述',
`requirement` text COMMENT '技术要求',
`teacher_id` bigint NOT NULL COMMENT '发布教师',
`status` tinyint DEFAULT '0' COMMENT '状态(0待审核 1已通过 2被驳回 3已被选)',
`max_student` int DEFAULT '1' COMMENT '最大可选人数',
`current_student` int DEFAULT '0' COMMENT '当前选择人数',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_teacher` (`teacher_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
4. 核心功能模块实现
4.1 课题申报与审核流程
课题申报采用状态机模式实现审核流程:
java复制@PostMapping("/topic/submit")
public Result submitTopic(@Valid @RequestBody TopicDTO dto) {
// 验证教师身份
Long teacherId = SecurityUtil.getCurrentUserId();
if (!userService.isTeacher(teacherId)) {
return Result.error("只有教师可以提交课题");
}
Topic topic = new Topic();
BeanUtils.copyProperties(dto, topic);
topic.setTeacherId(teacherId);
topic.setStatus(TopicStatus.PENDING.getCode());
topicService.save(topic);
// 发送站内通知给管理员
messageService.sendSystemMessage(
"新课题待审核",
String.format("教师%s提交了新课题《%s》",
SecurityUtil.getCurrentUser().getRealName(),
topic.getTitle()),
UserRole.ADMIN
);
return Result.success(topic.getId());
}
4.2 双向选择机制实现
学生选题采用Redis防止并发超选:
java复制public Result selectTopic(Long topicId) {
Long studentId = SecurityUtil.getCurrentUserId();
// Redis分布式锁
String lockKey = "topic:select:" + topicId;
try {
Boolean locked = redisTemplate.opsForValue()
.setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS);
if (!locked) {
return Result.error("操作太频繁,请稍后再试");
}
Topic topic = topicService.getById(topicId);
if (topic.getCurrentStudent() >= topic.getMaxStudent()) {
return Result.error("该课题已满员");
}
// 检查是否已选过课题
if (selectionRecordService.exists(
new QueryWrapper<SelectionRecord>()
.eq("student_id", studentId))) {
return Result.error("每人只能选择一个课题");
}
// 创建选题记录
SelectionRecord record = new SelectionRecord();
record.setTopicId(topicId);
record.setStudentId(studentId);
record.setSelectTime(new Date());
selectionRecordService.save(record);
// 更新课题人数
topicService.update(new UpdateWrapper<Topic>()
.setSql("current_student = current_student + 1")
.eq("id", topicId));
return Result.success("选题成功");
} finally {
redisTemplate.delete(lockKey);
}
}
4.3 进度管理模块
进度提交支持Markdown格式:
java复制@PostMapping("/progress/submit")
public Result submitProgress(@RequestBody ProgressDTO dto) {
Progress progress = new Progress();
progress.setStudentId(SecurityUtil.getCurrentUserId());
progress.setContent(dto.getContent());
progress.setType(dto.getType()); // 1周报 2月报 3阶段性报告
// Markdown转HTML存储
String html = markdownToHtml(dto.getContent());
progress.setHtmlContent(html);
progressService.save(progress);
// 通知指导教师
messageService.sendToTeacher(
"学生提交了新进度",
String.format("您的学生%s提交了新的%s,请及时查阅",
SecurityUtil.getCurrentUser().getRealName(),
ProgressType.of(dto.getType()).getDesc()),
getTeacherIdByStudent(SecurityUtil.getCurrentUserId())
);
return Result.success();
}
private String markdownToHtml(String markdown) {
// 使用commonmark-java实现转换
Parser parser = Parser.builder().build();
Node document = parser.parse(markdown);
HtmlRenderer renderer = HtmlRenderer.builder().build();
return renderer.render(document);
}
5. 安全防护与性能优化
5.1 安全防护措施
系统实现了多层安全防护:
- 接口级权限控制:
java复制@PreAuthorize("hasRole('TEACHER')")
@PostMapping("/topic/approve")
public Result approveTopic(@RequestParam Long topicId) {
// 仅教师可访问的审批接口
}
- XSS防护配置:
java复制@Bean
public FilterRegistrationBean<XssFilter> xssFilter() {
FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new XssFilter());
registration.addUrlPatterns("/*");
registration.setName("xssFilter");
return registration;
}
- PDF文件安全处理:
java复制public void validatePdf(File pdfFile) {
try (PDDocument document = PDDocument.load(pdfFile)) {
// 检查是否包含JavaScript
if (document.getDocumentCatalog().getAcroForm() != null) {
throw new SecurityException("PDF包含可执行表单");
}
// 检查嵌入式文件
for (PDPage page : document.getPages()) {
PDResources resources = page.getResources();
for (COSName name : resources.getXObjectNames()) {
PDXObject xobject = resources.getXObject(name);
if (xobject instanceof PDFormXObject) {
throw new SecurityException("PDF包含潜在危险元素");
}
}
}
}
}
5.2 性能优化实践
- 缓存策略设计:
java复制@Cacheable(value = "topics", key = "#status")
public List<TopicVO> getTopicsByStatus(Integer status) {
// 数据库查询逻辑
}
@CacheEvict(value = "topics", allEntries = true)
public void updateTopicStatus(Long topicId, Integer status) {
// 更新操作
}
- 数据库查询优化:
java复制public PageResult<TopicVO> searchTopics(TopicQuery query) {
return topicMapper.selectPage(
new Page<>(query.getPage(), query.getSize()),
new QueryWrapper<Topic>()
.like(StringUtils.isNotBlank(query.getTitle()), "title", query.getTitle())
.eq(query.getTeacherId() != null, "teacher_id", query.getTeacherId())
.eq(query.getStatus() != null, "status", query.getStatus())
.orderByDesc("create_time")
);
}
- 异步日志处理:
java复制@Async("logExecutor")
public void saveOperationLog(OperationLog log) {
operationLogMapper.insert(log);
}
6. 系统部署与运维
6.1 多环境部署方案
采用Profile区分环境配置:
yaml复制# application-dev.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/graduation_dev
生产环境推荐使用Docker Compose部署:
yaml复制version: '3.8'
services:
app:
image: graduation-manager:1.0.0
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
depends_on:
- mysql
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_DATABASE: graduation
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
volumes:
mysql_data:
6.2 监控与告警配置
集成SpringBoot Actuator:
yaml复制management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
使用Prometheus监控:
java复制@Bean
public MeterRegistryCustomizer<PrometheusMeterRegistry> configureMetrics(
@Value("${spring.application.name}") String appName) {
return registry -> registry.config().commonTags("application", appName);
}
7. 项目总结与扩展方向
在实际部署使用过程中,有几个关键点值得特别注意:
- 课题申报高峰期(通常学期初)需要提前做好服务器扩容准备
- 论文提交截止日前建议增加临时服务器资源
- 数据库需要定期备份选题记录和文档数据
系统还可以进一步扩展:
- 增加查重接口集成(对接知网/万方等查重系统)
- 开发微信小程序配套端
- 加入答辩安排管理模块
- 实现自动生成任务书功能
完整项目资源包包含:
- 完整可运行源码
- 数据库SQL脚本
- 部署文档
- 系统使用手册
- 万字技术文档
- 答辩PPT模板
项目已在多所高校实际应用,验证了其稳定性和实用性。对于计算机相关专业的毕业设计来说,开发这样一个实际可用的管理系统,既能展示全栈开发能力,又具有实际应用价值,是相当不错的选择。
