ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Spring Boot的学科竞赛管理系统:从状态机到全流程实现

基于Spring Boot的学科竞赛管理系统:从状态机到全流程实现 1. 项目整体规划与需求拆解先说结论如果你想找一个既能体现Java后端功底、又有完整业务闭环、还方便答辩讲清楚的毕设题目“学科竞赛管理系统”这个方向在同类型管理系统里算是性价比很高的选择。它不像电商系统那样业务链路长、逻辑复杂到讲不完也不像纯粹的CRUD那样显得单薄被评委质疑工作量不足。竞赛管理系统天然带有“流程管理”的属性——从竞赛发布、报名、作品提交、评审打分到成绩公示和证书发放整个生命周期可以拆出足够多的功能点同时又不会超出毕设的工作量合理范围。很多同学拿到这个题目后的第一反应是这不就是用户表、竞赛表、报名表做几个增删改查吗如果真这么做答辩现场大概率会被问得很难受。“学科竞赛管理系统”的核心价值不在于你用了多少张表而在于你是否把高校竞赛组织的“真实业务规则”梳理清楚。举个例子学生报名一个竞赛要不要指导老师审核一个学生能同时报多少个竞赛团队赛和个人赛如何区分竞赛的状态机是怎么流转的——从“草稿”到“报名中”再到“评审中”最后“已结束”这个状态由谁触发、触发条件是什么这些都是业务层面的问题而评委恰恰喜欢听到你对这些问题的思考和落地方案。再说技术选型。为什么大家都在用Spring Boot做毕业设计很简单——Spring Boot在业界的普及程度决定了它是“最容易被验证正确性”的选择。Spring Boot帮你把Spring的配置复杂度吃掉了内嵌的Tomcat也省去了单独部署服务器的麻烦。更关键的是Spring Boot的社区资料极其丰富你遇到任何技术问题搜索引擎上基本都能找到解决方案这对毕设开发周期来说是极大的保障。毕业设计的时间不是用来踩坑的而是用来出成果的。这个系统的目标使用场景也很明确高校内部学科竞赛的组织与管理。涉及三类角色学生参赛者、教师指导老师和评委、管理员竞赛组织者。整个系统的重心应该放在“竞赛全生命周期管理”上而不是做一个无所不包的校园信息平台——很多同学一膨胀就想加考勤、加图书管理、加二手交易方向完全走偏了。毕设的第一原则是“范围可交付”第二原则才是“功能丰富”。从技术架构上看这套系统最合理的搭配是Spring Boot 2.7 MyBatis-Plus MySQL 8.0 Vue 3或不分离的Thymeleaf取决于你的前端能力。如果你对前端有信心前后端分离如果时间紧张用Thymeleaf做服务端渲染也能完成功能而且能让答辩更聚焦于后端逻辑。后面我会逐个环节展开讲。2. 系统功能架构与数据库设计思路2.1 角色体系与权限边界我见过很多毕业生设计的权限模型上来就整RBAC五张表——用户表、角色表、权限表、用户角色关联表、角色权限关联表。听起来很专业但对这个项目来说是过度设计。学科竞赛管理系统的角色天然是固定的三类根本不需要动态配置角色的能力用Spring Security的hasRole()或者PreAuthorize(hasRole(STUDENT))就能解决权限问题。但有一个点容易被忽略指导老师和评委到底是不是同一种角色业务上他们是不同的人。指导老师负责指导学生的项目、审核报名资格评委负责给提交的作品打分。如果这张角色表不分清楚后面业务代码会写得非常别扭。我的建议是保留教师角色由管理员在“竞赛配置”时指定该竞赛的评委名单——评委本身是教师但在某个具体竞赛中承担评委职责。这样设计既能复用教师用户数据又能灵活配置评委身份。2.2 核心数据表与关系梳理数据库是整个系统的地基。我按业务模块把表拆出来sys_user用户表用户ID、用户名、密码BCrypt加密、姓名、学号/工号、角色类型、院系、专业、班级、电话、邮箱。这里要注意不要用明文存密码Spring Security自带的BCryptPasswordEncoder就够了。competition_info竞赛信息表竞赛ID、名称、类别学术类/技术类/创新创业类、级别校级/省级/国家级、主办方、参赛形式个人/团队、团队人数上限、报名开始时间、报名截止时间、状态、竞赛简介、附件通知等。registration_record报名记录表报名ID、竞赛ID、学生ID、团队ID、指导老师ID、报名时间、审核状态、作品文件路径、最终得分、排名、获奖等级。team_info团队表如果支持团队赛的话团队ID、团队名称、队长ID、竞赛ID。review_score评审打分表评分ID、评审专家ID、报名记录ID、各维度得分、总分、评语、评分时间。这里要保证一对多——一个作品由多个评委打分。notice_info公告表公告ID、标题、内容、发布时间、发布人。注意上面的关系报名记录表是整个系统的核心枢纽竞赛表、用户表、团队表、评审表都向它聚集。数据库外键我不建议物理建逻辑维护关系就行MyBatis-Plus用起来也更顺手。2.3 状态机的设计业务流转的骨架竞赛信息表里有个“状态”字段千万别小看它。状态的定义直接决定了业务流程的复杂度也决定了答辩时你能不能说清楚系统逻辑。我把竞赛状态设计为五段式草稿管理员创建但未发布仅自己可见报名中学生可以报名、提交资料评审中报名截止进入评审阶段学生不可再修改作品已结束评审完成成绩公布证书可下载已归档数据冻结仅可查询这个状态流转用过一个简单的状态机枚举类来控制不允许跳跃式变更。比如“草稿”不能直接跳到“评审中”必须先“发布”进入“报名中”。为什么这么设计因为每个状态对应一个用户操作集合草稿状态下学生看不到竞赛报名中打开报名入口评审中对学生关闭编辑权限已结束才允许查看成绩。如果状态没控制好就会出现学生已经报完名还能改作品评委还在打分管理员就误操作结束竞赛这类事故。2.4 报名流程整个系统的业务难点很多同学把“报名”做成一张表的insert然后就说报名功能做完了。实际业务里的报名流程是这样的学生提交报名信息个人赛填个人信息团队赛填成员名单→ 系统校验竞赛是否在报名期内→ 校验是否符合参赛条件比如限报名两个竞赛→ 如果该竞赛需要指导老师审核则推送审核通知给指导老师→ 指导老师审核通过后报名状态变为“已通过”→“报名截止后”管理员设置竞赛进入“评审中”系统自动锁住作品提交入口。这个流程里有两个易错点第一团队赛的成员数量校验必须在后端做绝不能只在前端限制否则有人绕过前端直接调接口就能破坏规则第二指导老师审核环节是可选配置——不是每个竞赛都需要指导老师。管理员在发布竞赛时可以勾选“是否需要指导老师审核”这样代码里用策略模式或者简单if判断即可覆盖两种场景。3. 核心技术选型与工程落地3.1 技术栈选型分析我在这类项目里最推荐的组合是Spring Boot 2.7.x MyBatis-Plus 3.5.x MySQL 8.0 Spring Security Nacos可选。为什么不用Spring Boot 3主要原因是Spring Boot 3基于Jakarta EE很多老教程和新手习惯的配置都不兼容而且版本要求JDK 17以上如果电脑上还在用JDK 8一堆环境问题会直接把开发进度拖垮。Spring Boot 2.7是一个久经考验的稳定版本资料多、排坑成本低对毕设来说是最稳妥的。如果你后续有余力再研究升级Spring Boot 3也不迟但不要在毕设阶段给自己额外加难度。持久层选MyBatis-Plus而不是纯MyBatis是因为Plus的BaseMapper已经内置了单表CRUD方法能省掉大量重复的XML配置。实际项目里超过80%的数据库操作都是单表单查直接selectList、selectPage就能搞定不需要写SQL。剩下的复杂查询比如竞赛报名统计报表再手写XML也不迟。MyBatis-Plus还有一个竞品没有的优势分页插件是在社区里被大量实战验证过的PageT对象直接用就行。前端这块我需要罗嗦两句。前后端分离是当前主流Vue 3 Element Plus的组合颜值高、组件全特别适合后台管理系统。但核心问题是你有没有足够时间前后端分离意味着你要处理跨域、Token传输、异步加载等等问题任何一个环节出bug都会耗费大量时间。如果不分离用Thymeleaf做服务端渲染所有数据通过Model直接渲染到HTML页面Spring Security的session机制天然适配反而更稳。我的建议是如果前端底子一般优先考虑Thymeleaf把开发时间省下来打磨后端功能完整性——答辩的真正加分项是你的后端业务逻辑不是页面炫不炫。3.2 项目工程结构规划一段清晰的代码结构在答辩PPT上放出来比口头说一万句都有用。我建议采用标准的maven多模块或包分层结构。这里直接写一个我常用的分层包结构com.campus.competition ├── controller # 接口入口层只做参数接收和结果返回 │ ├── admin # 管理员端接口 │ ├── teacher # 教师端接口 │ └── student # 学生端接口 ├── service # 业务逻辑层核心逻辑都在这层 │ ├── impl │ └── CompetitionStateMachine.java # 状态机 ├── mapper # MyBatis-Plus的Mapper接口层 ├── entity # 实体类一张表对应一个实体 ├── dto # 数据传输对象用于接收前端参数 ├── vo # 视图对象用于封装返回给前端的数据 ├── config # 配置类Security、WebMvc等 ├── common # 通用类统一返回结果、异常、工具类 └── utils # 工具类这个结构最大的好处是每一层职责清晰答辩时被问到“你这个项目怎么做到模块解耦的”时直接画这个图讲就行了。另外controller再按角色分包是因为不同端口的接口权限不同后续配Spring Security的permitAll()或hasRole()时路径规则会非常清晰。3.3 统一返回结果与全局异常处理写后端接口时最忌讳的是每个接口返回的数据结构都不一样——有的返回布尔值有的返回List有的直接返回Entity前端没法统一处理。我习惯定义通用返回体ResultT固定包含三个字段code状态码、message提示信息、data业务数据。所有接口统一返回Result.success(data)或Result.error(message)这样前端拿到任何响应只用判断code是否为200就知道业务是否成功。配套的还有全局异常处理用RestControllerAdvice拦截所有异常。如果你不做这层处理后端一抛异常默认返回的是一堆让前端摸不着头脑的技术堆栈信息甚至可能暴露内部SQL细节安全上也是隐患。我会在全局异常处理器里区分业务异常BusinessException和系统异常业务异常是可控的比如“报名时间已截止”、“该竞赛不允许修改作品”直接返回给用户友好的提示系统异常统一记录日志并返回“系统繁忙请稍后再试”避免把底层错误暴露到前端。这部分代码不多但给答辩带来的“工程规范感”提升非常明显。3.4 Spring Security认证与授权Spring Security有两种用法传统Session模式和无状态JWT模式。如果是前后端分离必须用JWT如果用了Thymeleaf用Session模式配合security:authorize标签就能控制页面元素的显示和隐藏开发量小很多。我简单说一下JWT模式的核心实现思路。用户登录成功后后端签发一个JWT Token包含用户ID、用户名、角色三个信息设置过期时间比如24小时。前端把Token存到localStorage每次请求在请求头里加Authorization: Bearer xxx。后端自定义一个JwtAuthenticationFilter继承Spring Security的OncePerRequestFilter在每个请求进来时解析Token、加载用户信息到SecurityContext。然后配置SecurityFilterChain放行/api/auth/login、/api/competition/list等公开接口其余全部要求认证接口级别再用PreAuthorize做细粒度控制。这里有一个新手常踩的坑自定义Filter一定要在SecurityFilterChain里显式添加到UsernamePasswordAuthenticationFilter之前否则Spring Security的默认过滤器链可能不会执行你的JWT认证逻辑。这个配置哪怕顺序错了一丁点你调试会非常崩溃——别人发Token过来后端却始终认为你没登录。4. 核心功能模块的实现细节4.1 竞赛发布与状态流转实现竞赛发布功能由管理员操作前端表单需要提交的字段包括竞赛名称、类别、级别、参赛形式、报名时间段、竞赛简介、附件等。关键点是管理员发布竞赛后系统自动执行一系列初始化动作——创建竞赛记录状态为“草稿”、上传附件、发送通知公告。这些操作不是简单地insert一张表而是需要在事务中完成。事务的使用是这个功能的重点。为什么用事务因为如果竞赛记录插入成功但公告创建失败或者附件关联失败数据库里就会留下一条“残缺”的竞赛信息。用Transactional标注在createCompetition方法上任何一步异常都整体回滚保证数据一致性。对应的我在CompetitionServiceImpl.createCompetition方法里用try-catch捕获异常回滚后抛出业务异常提示“竞赛发布失败请联系管理员”。答辩时能讲清楚这个逻辑说明你是真的考虑过数据安全问题的。状态流转实现上我会在CompetitionStateMachine里写一个changeState(Competition competition, CompetitionState targetState)方法。它的职责很简单校验当前状态是否允许流转到目标状态允许就更新不允许就抛出业务异常。然后所有状态变更都调用这个方法不直接改状态字段。举个例子“报名中”的竞赛要进入“评审中”就必须先确认当前状态确实是“报名中”同时isRegistrationClosed()当前时间晚于报名截止时间必须为true缺一个条件就拒绝流转。这种写法把状态管理的规则收敛到一个类里代码可读性和维护性都大大提升。4.2 学生报名与指导老师审核链路学生报名这个功能是整个系统中最容易出现逻辑漏洞的地方。完整实现思路如下报名接口接收竞赛ID和学生ID第一步检查竞赛状态是否为“报名中”如果不是直接拒绝第二步检查当前时间是否在报名时间窗口内第三步检查该学生是否已经报名过这个竞赛——要查一下报名记录表如果有记录就拒绝重复报名第四步如果该竞赛是团队赛还需要校验团队成员人数是否超出上限、成员是否有重复报名其他团队的情况第五步如果竞赛配置了指导老师审核创建一条状态为“待审核”的报名记录同时给指导老师生成待办通知如果没配置直接创建状态为“已通过”的报名记录。这里的第五步有个设计细节我要单独提一下。报名记录表里有个audit_status字段待审核、已通过、已驳回这个字段既要管指导老师审核又要管管理员审核。可能你会问如果两个角色都要审核怎么办我提供的方案是——指导老师审核在前管理员审核在后或者用audit_node字段记录当前需要哪个节点审核。但对于毕设规模来说我建议所有竞赛最多设一道审核关口要么指导老师审核要么管理员直接审核不要让同一张表同时承担两道独立的审核流程否则状态组合就会失控。指导老师端审核接口的逻辑是老师登录后只查自己名下待审核的报名记录点击通过时校验报名记录状态是否为“待审核”然后改成“已通过”。这里要强调一点审核操作本身要做操作记录简单做法是在audit_log表里记录操作人、操作类型、操作时间、操作对象ID。这个设计看上去不起眼但将来答辩被问到“如果老师误操作审核通过了怎么办”时你直接说“支持人工撤销并且审计日志里有完整记录”又是一项加分表现。4.3 作品提交与文件上传作品提交功能从技术上来说就是个文件上传但很容易做得不专业。常见的问题是文件重名互相覆盖、没有校验文件类型和大小、上传路径写死导致部署后找不到文件。我的实现思路是文件存储路径由配置文件管理不写在代码里。上传时用UUID作为新的文件名保存原始文件名到数据库文件类型只允许常见的PDF、ZIP、DOCX等大小限制在50MB以内具体看竞赛要求文件上传成功后文件路径和报名记录绑定学生在报名截止前可以重新上传替换旧文件截止后上传接口直接拒绝。这里再给一个容易踩的坑如果你把文件保存在项目根目录的uploads/文件夹下开发环境跑着没问题但打包部署成Jar包后会发现在Jar包内写文件是不可靠的——Jar包解压出来的文件系统是临时的重启就丢了。正确做法是配置一个绝对路径比如Linux服务器存/var/competition/uploads/Windows开发环境存D:/competition/uploads/。这个路径写到application.yml里通过配置读取部署时改配置文件即可。这个细节在答辩现场很能体现工程意识。4.4 评委评分与成绩统计评委评分模块的难点不在打分而在评分数据的组织。一个竞赛如果有N个评委M个作品那么评分表里会有N×M条记录。传统做法是让评委给每个作品逐一打分但这在真实业务中效率太低了——评委根本记不住哪个作品是哪个。正确做法是给评委一个“评分任务列表”的概念。评分任务表的设计是这样的管理员在竞赛进入“评审中”后点击“生成评审任务”系统自动为每个评委分配一组作品分配规则可以是随机分配也可以是按作品方向匹配甚至可以是管理员手动指定。评委登录后只看到分配给自己评审的作品列表点击进入评分页面按几个维度打分选题创新性、技术难度、完成度、实用价值、答辩表现总分自动算出来。这种设计不仅符合真实评审流程还天然解决了“所有评委都能看到所有作品”的作弊问题。评分完成后的成绩统计逻辑也要提前想好去掉一个最高分去掉一个最低分取平均分作为最终成绩如果评委超过5个人否则直接取平均分。排序后生成获奖等级奖项比例可以按竞赛类型配置——省级竞赛可能是一等奖5%、二等奖15%、三等奖30%校级竞赛可能比例更高。成绩统计完成后学生端就能看到自己的成绩和获奖信息了。4.5 数据看板与报表导出这个模块是我特别推荐你做的因为它是“工作量加码器”——功能不多但视觉效果和答辩亮点很足。具体做两块一是首页的统计卡片竞赛总数、进行中竞赛、报名总人次、获奖总人次二是按院系、按竞赛类别、按时间维度的统计图表。前端可以用ECharts画柱状图和饼图后端只需要提供对应的聚合查询。这里需要写几条带GROUP BY的SQL因为MySQL的统计函数性能非常好根本不需要引入额外的报表组件。我在这里也放一个个人偏好我习惯用SELECT DATE_FORMAT(create_time, %Y-%m)做按月分组统计近一年的报名趋势。这条SQL虽然简单但有业务说服力——学校领导最关心的是“今年的竞赛参与人数比去年涨了多少”这个图放答辩PPT里非常有冲击力。后端返回统计结果前端画个折线图整个系统的“管理决策支持”属性一下就出来了。5. 开发过程中的高频问题与排查思路5.1 环境搭建与版本兼容问题我见过太多同学在环境上耗掉三四天时间了。Spring Boot版本、JDK版本、Maven版本、MySQL版本任何一个错位都能整出各种莫名其妙的报错。首先说JDKSpring Boot 2.7要求JDK 8以上推荐直接用JDK 8稳定且绝大多数依赖库都兼容千万不要为了“尝鲜”去用JDK 17。Maven不要用最新版本3.8系列就够了新版Maven偶尔会对某些项目的构建方式过于“严格”。MySQL版本建议8.0因为5.7已经进入寿命末期了。但要记得改依赖mysql-connector-java在8.x版本中的groupId从mysql变成了com.mysqlartifactId变成了mysql-connector-j。很多网上的老教程用的是5.x的配置直接复制过来就会报ClassNotFound之类的狗血问题。驱动类名字也从com.mysql.jdbc.Driver变成了com.mysql.cj.jdbc.Driver。这些细节非常基础但卡起来一天都发现不了。5.2 MyBatis-Plus的经典坑MyBatis-Plus有几个常见问题我碰到过很多次先说分页插件。分页功能必须写一个MybatisPlusInterceptor配置类把PaginationInnerInterceptor注册进去。很多同学忘了这一步然后发现selectPage返回的数据永远是全部记录而不是分页后的数据甚至会报一些摸不着头脑的错误。这个配置在官方文档里写得很清楚但新手往往先写代码后看文档。另一个坑是字段名映射。MyBatis-Plus默认开启驼峰转下划线映射如果你数据库字段叫create_time实体类字段叫createTime默认是能映射上的。但是如果某个字段名里包含MySQL的关键字比如status、order、descMyBatis-Plus生成SQL时会报语法错误。解决办法是在TableField注解里用反引号指定真实的列名例如TableField(desc)。这种问题出现频率不低排查时多看一眼执行的SQL能节省大量时间。还有一个逻辑删除的坑。MyBatis-Plus支持TableLogic注解可以实现“删除”操作自动变成UPDATE ... SET deleted1查询自动带上WHERE deleted0。这个功能很好用但如果你一个实体加了逻辑删除另一个关联查询却没考虑这一点查出来的数据可能包含已删除的记录。特别注意如果加逻辑删除的字段名是deleted你必须保证所有数据库表里都有这个字段否则MP在自动生成SQL时只能部分生效甚至报错。5.3 上传文件的路径与权限问题文件上传功能上线后最常见的问题是在开发环境正常、部署到服务器就404。原因基本是我前面说到的路径问题。另外还有一个跨域问题如果你做了前后端分离前端通过http://localhost:8081/api/file/download/xxx这样的地址访问文件而后端跑在8080端口浏览器的同源策略会拦截这个跨域请求。解决办法要么配置CORS跨域资源共享把前端的域名地址加入允许跨域的名单里要么通过后端写一个文件下载接口返回ResponseEntitybyte[]前端用window.location.href触发下载。第二种方案更简单不需要引入CORS依赖配置。5.4 Spring Security配置顺序的坑Spring Security的过滤器链配置顺序极其严格务必按照“csrf禁用→cors开启→authorizeHttpRequests规则→formLogin/httpBasic禁用→sessionManagement策略→自定义过滤器添加”的次序来写。很多同学喜欢把authorizeHttpRequests放在最后结果发现所有请求都被拦截了连登录接口都访问不了。还有一个隐蔽的问题如果你配置了JWT认证但没有显式处理匿名用户访问受保护资源的情况Spring Security默认会返回403或者重定向到登录页对前后端分离项目来说两种都不对。正确做法是配置authenticationEntryPoint返回JSON格式的“未登录或登录已过期”提示状态码设为401。这样前端axios拦截器就能统一跳转登录页。5.5 答辩前常见的性能与安全提问点评委最爱问的除了业务逻辑还有系统安全和抗压能力。提前做好准备比现场编强一百倍。常规问法包括密码存的方式、如果有人恶意高频调用报名接口怎么办、数据库数据量大时怎么办。密码这块已经说过用BCrypt加密可以自信说你用到了加盐哈希算法。接口防刷最简单的方案是定义一个基于IP或者用户ID的限流拦截器用本地缓存比如Caffeine统计单位时间内的请求次数超过阈值就拒绝服务。高性能这块MySQL加上合适的索引比如competition_id和user_id的联合索引单表几万条数据量完全扛得住。这些回答准备到位答辨现场就很从容了。6. 项目拓展方向与个人实操建议6.1 有价值但不复杂的拓展点如果你做完核心功能还有剩余时间推荐加这几个拓展一是消息推送采用WebSocket实现管理员发布竞赛时在线学生能实时收到通知这里可以讲Spring的WebSocketHandler和前端new WebSocket()的配合是个不错的技术亮点二是Excel批量导入和导出用EasyExcel可以非常方便地把报名名单导出成Excel这对管理员来说是最实用的功能之一三是比赛材料在线预览PDF的在线预览可以用浏览器的pdf.js实现代码量不大但视觉效果非常好。上面这三个拓展点技术难度都控制在单日工作量以内但都能给系统增加“真正能解决业务问题”的说服力。毕设项目不怕功能少就怕功能杂而不精。把核心链路做扎实一两个亮点功能做漂亮答辩就稳了。6.2 开发节奏建议与时间管理最后聊聊排期。基于这个系统的功能量我根据自己带学生做毕业设计的经验给的节奏建议是第一周做需求分析、数据库设计和项目骨架搭建第二周完成用户注册登录、权限控制和竞赛管理模块第三周完成报名、审核和作品提交第四周完成评分、成绩统计和数据看板第五周集中测试、修补bug、编写文档和答辩PPT。如果时间紧凑压缩到三周半也来得及但节奏要做好。实际开发中还有一个很重要的提醒——务必做好git版本管理。哪怕就一个人写也要每完成一个模块打一个commit不要把所有代码堆到最后一次性提交。一方面中间代码写坏了你能随时回退这个功能省下来的时间和风险绝对值得你提前学会用Git另一方面答辩时老师问“你的开发过程是怎样的”你可以直接展示你的commit记录证明这是一步一步搭起来的而不是网上找个开源项目改个名字就交差。毕设这件事过程痕迹和最终结果同样有分量。6.3 关于这个系统的最后一点心得从我接触过的实际使用反馈来看竞赛管理系统在高校IT部门的受欢迎程度远高于预期。很多学院每年要组织几十项学科竞赛承办方和参赛学生都缺乏一个统一的数字化入口这套系统切中的正是这个真实痛点。作为毕业设计它不仅在学术上完整在落地价值上也可圈可点。如果你愿意在功能设计上多花一点心思去调研本校的真实业务流程真正的需求洞察会让你的毕设立意高出一个档次。就我个人而言在带过十几个由学生独立完成的Spring Boot管理类毕业设计之后最深的感受是能把一门课的基本功串联成一套能跑起来的系统本身就是毕业设计最大的意义。如果你恰好也在这个选题上希望这篇内容能给你一些启发也祝你的项目答辩顺利。
返回列表