毕业设计实战:基于Java+SpringBoot的毕业论文管理系统设计与实现,从需求到测试全流程拆解,新手也能轻松通关!

106 阅读20分钟

毕业设计实战:基于Java+SpringBoot的毕业论文管理系统设计与实现,从需求到测试全流程拆解,新手也能轻松通关!

谁懂啊!当初做毕业论文管理系统毕设时,光课题信息表和选题申请表的外键关联就卡了5天——一开始没给选题申请表设“课题id”外键,查某课题的所有申请记录时数据全乱套,导师看了直接让我“重新梳理数据库实体关系”😫 后来踩遍无数坑才摸出一套高效落地流程,今天把需求分析、技术选型、功能实现到测试的细节全说透,宝子们不用再熬夜改代码,轻松搞定毕设!

一、先搞懂“毕业论文管理系统要啥”!需求分析别瞎蒙

刚开始我跳过需求分析就写代码,花两周加了个“论文相似度智能检测功能”,结果导师一句“核心是课题管理、选题申请、论文提交,不是复杂算法”直接打回重改!后来才明白,需求分析得先抓准“谁用系统、要干啥”,这步做对,后面少走90%弯路。

1. 核心用户&功能拆解(踩坑后总结版)

毕业论文管理系统就三类核心用户:管理员指导教师学生(别加“评阅教师子角色”!我当初加了后,权限逻辑混乱,指导教师能改评阅分数,最后砍掉才顺畅):

  • 管理员端(必做功能):
    • 基础管理:用户信息管理(新增/修改/删除学生/教师账号)、字典管理(维护学院/班级/课题类型)、个人中心(修改密码/更新资料)
    • 教学管理:指导教师管理(添加教师信息、分配课题权限)、评阅教师管理(维护评阅账号、设置评阅范围)、课题类型管理(新增/编辑课题分类)
    • 论文管理:课题信息管理(审核教师提交的课题、标记审核状态)、选题申请管理(查看学生选题申请、协助处理冲突)、毕业论文管理(查看学生提交的论文、导出论文文件)
    • 内容管理:公告信息管理(发布答辩通知、维护公告类型)、公告类型管理(新增“答辩安排”“成绩公示”等类型)
  • 指导教师端(核心功能):
    • 课题操作:提交课题信息(填写课题名称/内容/要求)、查看课题审核状态、修改未通过的课题信息
    • 学生管理:查看指导学生列表、分配课题任务(上传参考文献/阶段要求)、审核学生阶段文档、给论文打分写评语
    • 信息查看:浏览系统公告、查看选题申请记录、导出学生论文
  • 学生端(核心功能):
    • 选题操作:浏览可申请课题、提交选题申请、查看申请结果
    • 论文操作:提交毕业论文(上传论文文件、填写论文标题)、查看教师评语和分数、提交阶段文档(响应课题任务要求)
    • 信息查询:查看个人信息(学号/学院/班级)、浏览公告通知、查看课题任务和参考文献

2. 需求分析避坑指南(血泪教训!)

  • 别光靠“空想”!找2个同学分别模拟教师和学生提意见:比如有学生说“想快速知道选题申请是否通过”,我才加了“申请状态标色”(待审核标黄色/已通过标绿色/已拒绝标红色),比瞎加“相似度检测”实用多了
  • 一定要画用例图!用DrawIO画简单版,标清“管理员-审核课题信息”“学生-提交毕业论文”,跟导师汇报时,比光说“我要做XX功能”直观10倍(当初没画,导师听25分钟还没get到逻辑)
  • 写“需求规格说明书”!不用复杂,把“功能描述、约束条件”写清楚(比如“课题名称非空”“论文文件仅支持PDF”“选题申请截止时间不能早于课题发布时间”),编码时对着做,不会跑偏

3. 可行性分析别敷衍!3点写清楚就能过

导师超爱问“你这系统可行吗”,别只说“我觉得可行”,从3个核心角度写,显得专业:

  • 技术可行性:Java、SpringBoot、MySQL、JSP都是课堂学过的,图书馆有《SpringBoot实战教程》《MySQL数据库设计与优化》,遇到问题能查资料(别用Vue!我当初想试前后端分离,论文文件上传接口卡了一周,换回JSP才顺利)
  • 经济可行性:所有工具全免费!IDEA(社区版)、MySQL、Tomcat官网直接下,不用花钱买版权,答辩时说“开发成本为0”,导师会觉得你懂成本控制
  • 操作可行性:界面参考主流教务系统(如学校的毕业论文管理平台),按钮布局简洁,我找同学测试,4分钟就学会提交选题、上传论文,导师直接认可

二、技术选型别跟风!这套组合稳到爆

刚开始我跟风用Java+Vue+Redis,结果“学生选题申请缓存”卡了6天——Redis的持久化配置没设对,重启后申请状态全丢😫 后来换成Java 8+SpringBoot 2.5.6+MySQL8.0+Tomcat9+IDEA 2022+JSP,新手友好度拉满,调试效率翻两倍!

1. 技术栈详细对比(附避坑提醒)

宝子们别盲目选“最新技术”,稳定比炫酷重要!我整理了5个核心工具的选择理由和坑点,直接抄:

技术工具为啥选它避坑提醒!(重点!)
Java 8语法简洁,支持面向对象编程,学习资料丰富,SpringBoot 2.5.6对其兼容性最佳别用Java 11+!部分SpringBoot依赖对高版本支持差,会出现“类加载失败”错误
SpringBoot 2.5.6简化配置(不用手动整合SSM),自带Tomcat插件,支持热部署,开发效率高别用2.7+版本!新手容易踩“循环依赖”坑,调试时找不到报错原因
MySQL 8.0支持事务和外键,存课题、论文、申请记录足够用,占内存小,支持utf8mb4编码安装时设“utf8mb4”编码!我当初用默认编码,学生姓名含特殊字符(如“䞍”)乱码,查2小时才解决
Tomcat 9.0和SpringBoot、JSP适配最好,启动稳定,极少出现“端口占用”问题别用Tomcat 10!会出现“Servlet API包名变更”,答辩时系统崩了就完了
IDEA 2022对SpringBoot支持好,自带代码提示,调试工具直观,免费开源别更到2023+版本!高版本对老电脑兼容性差,编译项目时经常卡顿闪退

2. 开发环境搭建(step by step 实操)

很多宝子卡在“环境配置”,跟着步骤来超简单,我当初一次成功:

  1. 装JDK 1.8:记住安装路径(比如D:\Java\jdk1.8.0_301),配置“JAVA_HOME”环境变量,Path中添加“%JAVA_HOME%\bin”,cmd输入“java -version”显示版本即成功
  2. 装IDEA 2022(社区版):选“IntelliJ IDEA Community Edition”,首次打开勾选“SpringBoot”“MySQL”插件,自动安装
  3. 装MySQL 8.0:用Navicat管理(可视化工具超方便),新建数据库“graduation_thesis_system”,编码设“utf8mb4”,排序规则选“utf8mb4_general_ci”
  4. 配SpringBoot项目:在IDEA中新建“Spring Initializr”项目,勾选“Spring Web”“MyBatis Framework”“MySQL Driver”依赖,自动生成application.properties配置文件
  5. 测试连接:在application.properties中配置MySQL连接信息(url、用户名、密码),写一个“查询学生列表”接口,运行后能返回数据即完成初始化

3. 架构图一定要画!答辩加分项

用DrawIO画SpringBoot分层架构图,标清“表现层(JSP)-控制层(Controller)-业务层(Service)-数据访问层(Mapper)-数据库(MySQL)”:比如学生点“提交选题申请”→JSP页面传请求→Controller接收→Service校验课题状态→Mapper操作数据库→返回申请结果。去年答辩时,评委特意夸这图“逻辑清晰”,比光说“我用了SpringBoot+MySQL”专业多了!

三、数据库设计:别让表关联坑了你

这部分是毕设的“核心骨架”,我当初没关联“课题信息表”和“选题申请表”,查“某课题的所有申请记录”要写3层嵌套SQL,调试到凌晨1点😫 后来按“实体-属性-关系”设计,终于理清了。

1. 核心实体&属性(附ER图绘制技巧)

先确定“实体”(管理员、指导教师、学生、课题信息、选题申请、毕业论文),再想“属性”,别漏关键字段!我整理了必做的10张表,直接照着画ER图:

  • 学生表(yonghu):id(主键)、yonghu_name(学生姓名)、yonghu_uuid_number(学号,唯一)、yonghu_phone(手机号)、xueyuan_types(学院)、banji_types(班级)、yonghu_email(电子邮箱)
  • 课题信息表(keti):id(主键)、keti_name(课题名称)、keti_text(课题内容)、zhidaojiaoshi_id(关联指导教师)、keti_types(课题类型)、keti_yesno_types(审核状态:0=待审核,1=已通过,2=已拒绝)
  • 选题申请表(xuantishenqing):id(主键)、yonghu_id(关联学生)、keti_id(关联课题)、xuantishenqing_uuid_number(申请编号,唯一)、xuantishenqing_yesno_types(申请状态)、xuantishenqing_yesno_text(申请结果说明)
  • 毕业论文表(biyeluenwen):id(主键)、yonghu_id(关联学生)、zhonggaoshenhe_name(论文标题)、zhonggaoshenhe_file(论文文件路径)、biyeluenwen_num(论文分数)、biyeluenwen_yesno_text(教师评语)

画ER图用Visio或亿图,记住3个规则:

  1. 矩形代表“实体”(比如“学生”“课题信息”)
  2. 椭圆代表“属性”(比如学生的“学院”“班级”)
  3. 菱形代表“关系”(比如“学生-选题申请”是一对多,一个学生可提交多个申请;“指导教师-课题信息”是一对多,一个教师可提交多个课题) 避坑提醒:别把“论文文件、学生头像”存数据库!我当初存二进制导致数据库崩溃,改成存“文件路径”(比如/static/paper/student1.pdf、/static/photo/student1.jpg)才对。

2. 数据库物理设计(附建表SQL示例)

ER图画好后,转成实际表,字段类型和约束别瞎设!比如“论文分数”用INT,“申请编号”用VARCHAR(50),“学号”设UNIQUE约束,避免重复。

给宝子们贴“课题信息表”和“选题申请表”的建表SQL,复制到Navicat就能用:

-- 课题信息表
CREATE TABLE `keti` (
  `id` INT NOT NULL AUTO_INCREMENT COMMENT '课题ID',
  `keti_name` VARCHAR(100) NOT NULL COMMENT '课题名称',
  `keti_text` TEXT DEFAULT NULL COMMENT '课题内容',
  `zhidaojiaoshi_id` INT DEFAULT NULL COMMENT '关联指导教师ID(外键)',
  `keti_types` INT DEFAULT NULL COMMENT '课题类型(1-软件工程,2-人工智能,3-大数据)',
  `keti_yesno_types` INT DEFAULT 0 COMMENT '审核状态(0-待审核,1-已通过,2-已拒绝)',
  `keti_yesno_text` VARCHAR(200) DEFAULT NULL COMMENT '审核结果说明',
  `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `fk_teacher_keti` (`zhidaojiaoshi_id`),
  CONSTRAINT `fk_teacher_keti` FOREIGN KEY (`zhidaojiaoshi_id`) REFERENCES `zhidaojiaoshi` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='课题信息表';

-- 选题申请表
CREATE TABLE `xuantishenqing` (
  `id` INT NOT NULL AUTO_INCREMENT COMMENT '申请ID',
  `yonghu_id` INT DEFAULT NULL COMMENT '关联学生ID(外键)',
  `keti_id` INT DEFAULT NULL COMMENT '关联课题ID(外键)',
  `xuantishenqing_uuid_number` VARCHAR(50) DEFAULT NULL COMMENT '申请编号(唯一)',
  `xuantishenqing_yesno_types` INT DEFAULT 0 COMMENT '申请状态(0-待审核,1-已通过,2-已拒绝)',
  `xuantishenqing_yesno_text` VARCHAR(200) DEFAULT NULL COMMENT '申请结果说明',
  `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_apply_uuid` (`xuantishenqing_uuid_number`),
  KEY `fk_student_apply` (`yonghu_id`),
  KEY `fk_keti_apply` (`keti_id`),
  CONSTRAINT `fk_student_apply` FOREIGN KEY (`yonghu_id`) REFERENCES `yonghu` (`id`),
  CONSTRAINT `fk_keti_apply` FOREIGN KEY (`keti_id`) REFERENCES `keti` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='选题申请表';

3. 表关联测试!别等编码才发现错

建完表一定要测关联!比如在“课题信息表”插数据(id=1,名称=“基于Java的图书管理系统”,教师ID=1,类型=1,状态=1),在“选题申请表”插关联数据(学生ID=1,课题ID=1,状态=0),用JOIN查询“某课题的所有申请记录”:

SELECT s.yonghu_name, s.yonghu_uuid_number, a.xuantishenqing_uuid_number, 
       a.xuantishenqing_yesno_types, a.create_time
FROM xuantishenqing a
JOIN yonghu s ON a.yonghu_id = s.id
WHERE a.keti_id = 1;

如果能查出“学生姓名+学号+申请编号+申请状态+创建时间”,说明关联没问题;如果报错“Cannot add or update a child row”,大概率是外键没设对,赶紧检查表结构。

四、功能实现:核心模块操作+页面设计

不用做所有功能!先搞定3个核心模块,答辩时足够出彩。每个模块我都附关键操作逻辑和页面设计要点,宝子们直接套就行。

1. 管理员端:课题信息管理模块(必做!)

这是管理员的核心功能,实现“课题审核+信息维护”,重点说“课题名称唯一性校验”和“审核状态同步”——别漏这两步,我当初就是这里踩了大坑!

(1)关键操作逻辑
  1. 审核课题前,校验“课题名称非空”“指导教师已存在”(缺一项提示“请完善课题信息”);
  2. 审核通过时,同步更新课题状态为“已通过”,并记录审核时间;
  3. 审核拒绝时,必须填写拒绝理由(避免教师不清楚未通过原因),同步更新状态为“已拒绝”。
(2)页面设计要点(JSP+Bootstrap)

页面标题:管理员-课题信息管理页面
(插入图片位置:此处放“课题信息管理页面截图”,需包含以下元素)

  • 筛选区:
    • 输入框:课题名称(模糊查)、指导教师姓名(模糊查)
    • 下拉框:课题类型(全部/软件工程/人工智能/大数据)、审核状态(全部/待审核/已通过/已拒绝)
    • 按钮:“查询”(蓝色btn-primary)、“刷新列表”(灰色btn-default)
  • 课题列表区:
    • 表格列名:课题名称、指导教师、课题类型、课题内容、审核状态、创建时间、操作
    • 状态显示:待审核标黄色/已通过标绿色/已拒绝标红色
    • 操作按钮:待审核显示“审核”(蓝色btn-info),已审核显示“查看详情”(蓝色)、“编辑”(橙色btn-warning)
  • 审核弹窗:
    • 只读信息:课题名称、指导教师、课题内容、创建时间
    • 填写项:审核结果(单选“通过”“拒绝”)、审核理由(文本域,拒绝时必填)
    • 按钮:“提交审核”(绿色btn-success)、“取消”(灰色)
(3)避坑提醒
  • 审核理由校验!加逻辑:
    // 审核拒绝时校验理由
    if (result == 2 && StringUtils.isEmpty(auditReason)) {
        return Result.error("拒绝课题需填写审核理由!");
    }
    // 更新课题状态
    Keti keti = ketiService.getById(ketiId);
    keti.setKetiYesnoTypes(result); // 1=通过,2=拒绝
    keti.setKetiYesnoText(auditReason);
    ketiService.updateById(keti);
    return Result.success("课题审核完成!");
    

2. 学生端:选题申请模块(核心需求!)

学生用系统的核心是“选课题-提交申请-查结果”,流程别复杂:浏览课题列表→选择课题→填写申请说明→提交,我当初漏了“同一课题只能申请一次”校验,导致学生重复申请,补了半天逻辑才好。

(1)关键操作逻辑
  1. 提交申请前,校验“未重复申请该课题”“课题状态为已通过”(不满足提示“无法申请此课题”);
  2. 自动生成唯一“申请编号”(格式:SQ+日期+随机数),方便后续查询;
  3. 提交成功后,默认申请状态为“待审核”,同步显示“申请已提交,等待教师审核”提示。
(2)页面设计要点(JSP+Bootstrap)

页面标题:学生-选题申请页面
(插入图片位置:此处放“选题申请页面截图”,需包含以下元素)

  • 课题列表区:
    • 筛选栏:课题类型(下拉选)、指导教师(输入框模糊查)、“查询”按钮
    • 表格列名:课题名称、指导教师、课题类型、课题内容、操作
    • 操作按钮:“申请此课题”(绿色,仅状态为“已通过”的课题显示)
  • 申请弹窗:
    • 只读信息:课题名称、指导教师、课题内容
    • 填写项:申请说明(文本域,选填,说明申请优势)
    • 按钮:“提交申请”(绿色)、“取消”(灰色)
  • 我的申请区:
    • 表格列名:申请编号、课题名称、申请状态、申请时间、操作
    • 状态显示:待审核标黄色/已通过标绿色/已拒绝标红色
    • 操作按钮:“查看详情”(蓝色)、“取消申请”(仅待审核显示)
(3)避坑提醒
  • 重复申请校验与编号生成!加逻辑:
    // 校验是否重复申请
    LambdaQueryWrapper<Xuantishenqing> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Xuantishenqing::getYonghuId, studentId)
           .eq(Xuantishenqing::getKetiId, ketiId);
    if (xuantishenqingService.count(wrapper) > 0) {
        return Result.error("您已申请过此课题,请勿重复提交!");
    }
    // 校验课题状态
    Keti keti = ketiService.getById(ketiId);
    if (keti.getKetiYesnoTypes() != 1) {
        return Result.error("该课题未通过审核,无法申请!");
    }
    // 生成唯一申请编号
    String uuid = "SQ" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + RandomUtils.nextInt(1000, 9999);
    xuantishenqing.setXuantishenqingUuidNumber(uuid);
    xuantishenqing.setXuantishenqingYesnoTypes(0); // 0=待审核
    xuantishenqingService.save(xuantishenqing);
    return Result.success("申请已提交,等待教师审核!");
    

3. 指导教师端:毕业论文评分模块(答辩亮点!)

这个功能最能体现“论文管理闭环”,导师超爱问!核心是“查看学生论文-打分写评语-提交结果”,别漏“分数范围校验”,不然分数超出0-100分范围,不符合评分逻辑。

页面设计要点(JSP+Bootstrap)

页面标题:指导教师-毕业论文评分页面
(插入图片位置:此处放“毕业论文评分页面截图”,需包含以下元素)

  • 筛选区:
    • 输入框:学生姓名(模糊查)、学号(精确查)
    • 下拉框:评分状态(全部/未评分/已评分)
    • 按钮:“查询”(蓝色)、“批量导出论文”(紫色btn-info)
  • 论文列表区:
    • 表格列名:学生姓名、学号、论文标题、提交时间、论文文件、评分状态、操作
    • 论文文件:“下载”按钮(点击下载PDF)
    • 操作按钮:未评分显示“评分”(绿色),已评分显示“查看评分”(蓝色)
  • 评分弹窗:
    • 只读信息:学生姓名、学号、论文标题、提交时间、论文预览(嵌入PDF插件)
    • 填写项:论文分数(输入框,限制0-100)、评语(富文本编辑器,必填)
    • 按钮:“提交评分”(绿色)、“取消”(灰色)
(3)避坑提醒
  • 分数范围校验!加逻辑:
    // 校验分数范围
    if (score < 0 || score > 100) {
        return Result.error("论文分数需在0-100分之间,请重新输入!");
    }
    // 校验评语非空
    if (StringUtils.isEmpty(comment)) {
        return Result.error("请填写论文评语!");
    }
    // 更新论文评分
    Biyeluenwen paper = biyeluenwenService.getById(paperId);
    paper.setBiyeluenwenNum(score);
    paper.setBiyeluenwenYesnoText(comment);
    paper.setBiyeluenwenYesnoTypes(1); // 1=已评分
    biyeluenwenService.updateById(paper);
    return Result.success("论文评分提交成功!");
    

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

五、测试别敷衍!这3步让答辩不翻车

很多宝子觉得“功能能跑就行”,结果答辩时评委一测就出问题!我当初没测“论文分数为负数”场景,导致系统允许无效分数入库,导师说“不符合评分逻辑”,当场扣分😫 测试一定要针对性做!

1. 功能测试(必测3个模块)

别全测!重点测“核心功能”,我整理了测试用例表,直接填结果:

(1)课题信息管理测试(表1:课题测试用例)
测试场景操作步骤预期结果实际结果测试结论
审核拒绝不填理由选待审核课题→点“审核”→选“拒绝”→不填理由→提交提示“拒绝课题需填写审核理由!”
课题名称为空审核课题名称留空→提交审核→选“通过”→提交提示“请完善课题信息(课题名称不能为空)!”
正常审核通过选待审核课题→点“审核”→选“通过”→填理由→提交提示“课题审核完成!”,状态变为已通过
(2)选题申请测试(表2:申请测试用例)
测试场景操作步骤预期结果实际结果测试结论
重复申请同一课题选已申请的课题→点“申请此课题”→提交提示“您已申请过此课题,请勿重复提交!”
申请未通过审核的课题选状态为“已拒绝”的课题→点“申请此课题”→提交提示“该课题未通过审核,无法申请!”
正常提交申请选状态为“已通过”的课题→填申请说明→提交提示“申请已提交,等待教师审核!”
(3)论文评分测试(表3:评分测试用例)
测试场景操作步骤预期结果实际结果测试结论
分数为负数输入分数-5→填评语→提交提示“论文分数需在0-100分之间,请重新输入!”
不填评语评分输入分数80→不填评语→提交提示“请填写论文评语!”
正常提交评分输入分数85→填评语→提交提示“论文评分提交成功!”,状态变为已评分

2. 兼容性测试(容易忽略的点)

别只在自己电脑测!答辩时评委可能用不同浏览器,我当初没测IE,结果论文预览插件加载失败,赶紧加兼容性JS才好:

  • 浏览器测试:Chrome、Firefox、Edge、IE11(重点测IE,兼容性最差)
  • 分辨率测试:1920×1080、1366×768(别让页面出现横向滚动条,用Bootstrap的“container”布局,加“overflow-x: hidden”)

3. 测试报告要写好!答辩加分

把测试结果整理成“测试报告”,含“目的、范围、用例、结果、问题总结”,导师会觉得你“做事严谨”。比如:

  • 问题总结:“IE浏览器下论文预览插件加载失败,通过添加IE专属JS(if (navigator.userAgent.indexOf("MSIE") > 0) { ... })修复;分数为负数能提交,加范围校验修复”
  • 测试结论:“核心功能(课题审核、选题申请、论文评分)均通过测试,无严重bug;兼容性问题已修复,系统可正常使用”

六、答辩准备:3个加分小技巧

毕设不仅要做出来,还要说清楚!我当初准备了这3点,导师直接给“良好”:

  1. 演示流程要顺畅:提前录演示视频(怕现场系统崩),按“管理员审核课题→学生提交选题申请→指导教师审核申请→学生上传论文→指导教师评分”的流程来,别跳步
  2. 重点讲“你解决了啥问题”:比如“一开始学生能重复申请课题,加重复校验解决;论文分数能超100分,加范围校验修复;表关联错误导致查不到申请记录,重新设计外键解决”,比光说“我用了SpringBoot+MySQL”有亮点
  3. 准备常见问题:导师大概率问“为啥选SpringBoot不选SSM”“数据多了怎么优化”,提前答:“SpringBoot简化配置,新手容易上手;数据多就加索引(如选题申请表的keti_id和yonghu_id联合索引),优化查询速度,还能分表存储历史论文数据”

最后:毕设通关的小私心

以上就是基于Java+SpringBoot的毕业论文管理系统从0到1的避坑干货!毕设没那么难,关键是找对方法,别瞎做复杂功能。

需要核心源码(带注释,直接能跑)、数据库脚本(含测试数据)、ER图模板的宝子,评论区扣“毕业论文管理系统”,我私发你;卡在某个模块(比如课题审核、论文评分),也可以留言,我看到必回!

点赞收藏这篇,下次找流程不迷路~祝宝子们毕设顺利,轻松毕业!😘