Spring Boot Vue 人事管理系统这个选题我太熟了。近几年毕业设计里前后端分离的管理系统几乎霸榜而人事管理系统又因为业务逻辑清晰、功能模块标准、可扩展性强成了很多同学的优先选择。我这个帖子就围绕这个选题展开从选题逻辑、技术架构、功能设计、论文组织到答辩准备以“过来人”的口吻把整个实操过程掰开揉碎讲一遍。不管你是刚拿到题目不知从哪下手还是已经写了半篇论文卡在技术实现上这篇内容都值得你花十分钟看完。1. 项目概述与选题价值1.1 为什么人事管理系统经久不衰人事管理系统在历年毕业设计中出现的频率极高几乎每届都有。这不是因为大家没创意而是因为这个业务场景本身有很强的标本意义。一家公司无论规模大小都需要管人——员工信息、考勤记录、薪资核算、部门架构、请假审批、岗位变动这些都是再典型不过的“增删改查”业务。也就是说只要你把人事系统做好你就已经掌握了绝大多数管理类信息系统的核心开发模式。更深一层来看人事管理系统正好踩在毕业设计的评分点上功能完整能体现“系统设计”能力业务逻辑适中不复杂到做不完也不简单到没东西写权限管理天然需要区分角色能体现你对RBAC模型的理解数据关系多样员工、部门、考勤、薪资之间有关联查询能给数据库设计加分1.2 这个选题能锻炼什么核心能力选Spring Boot Vue这个组合本身就是冲着“实用”和“主流”去的。通过这个项目你能真正练到以下能力第一前后端分离的开发思维。以前很多课程设计是JSP Servlet一把梭页面和后端代码混在一起。而Spring Boot Vue完全是另一套逻辑后端只写接口前端只调接口两边通过JSON通信。这种模式是你进企业之后百分之九十会遇到的。第二接口设计与状态码规范。你不能随便返回一个Map就完事得设计统一的响应体结构什么情况返回200什么情况返回401什么情况返回500这些都需要周密考虑。第三权限控制从理论到落地。用户登录之后能访问哪些菜单、能操作哪些按钮怎么用拦截器或过滤器实现怎么在前端做路由守卫这些做一遍才能真正理解。第四数据库设计的约束与优化。员工表、部门表、薪资表之间如何设计外键如何建索引如何避免冗余这比JSP时代一张表打天下的做法要专业得多。我用一个类比来帮没接触过前后端分离的同学理解传统的JSP模式像去食堂打饭厨师后端直接把HTML饭菜打好端给你你只能吃他配好的。前后端分离则像自助餐后端把菜纯JSON数据放在取餐区前端按自己的菜单Vue页面模板任意搭配吃多少、怎么拼你自己说了算而且换一个前端展示方式比如从网页换成手机App后端不用改。1.3 适合哪些同学参考这个题目適应面很广。如果你基础偏弱但愿意按时敲代码花一个月把基础模块做出来完全可行如果你有一定编码经验那就可以在完善功能之外加上更多设计层面的思考——比如使用Redis缓存登录态、接口幂等性处理、使用EasyExcel做薪资报表导出这些都能成为论文里的亮点。当然我也要说清楚这个选题也有它的局限。最大的问题是“撞车率高”同一届里选人事系统的可能有好几个关键是如何做出差异。差异化的方法很简单不要在基础功能上做文章而是找一个真正能落到实处的特色功能。比如有的同学加了“智能排班”用简单算法每周自动生成值班表有的同学加了“招聘管理”把简历上传、筛选、面试安排串成一条流程。这些功能不需要高深算法但能明显提升工作量显示度和系统完整度。2. 系统整体设计与技术架构解析2.1 前后端分离的整体架构整个系统按物理结构分为两个部分前端工程vue-manage-system这类基础框架负责页面展示和交互后端工程springboot-hr-server负责业务逻辑处理和数据库操作。两者独立启动、独立部署前端通过Axios或者Fetch调用后端的RESTful API接口。实际开发时我建议你把工程目录分成两个文件夹比如hr-frontend和hr-backend不要混在一起。最终的论文架构图里也可以沿用这个结构评审老师看到目录就明白你走的是正规前后端分离路线而不是在一个工程里“硬拆”出来的。这个架构的核心环节是接口交互。前端和后端之间走HTTP协议传输的是JSON格式数据。整个过程很像两人传纸条但纸条上有固定格式code表示状态message表示提示信息data表示真正的业务数据。前端拿到响应后先判断code再处理data。这么做的好处是后端可以统一处理异常前端只需要维护一套解析逻辑。2.2 后端技术选型详解后端技术栈我推荐按下面这套来不是说非得最新而是“成熟稳定、资料多、遇到问题搜得到解决方案”对你最重要JDK 1.8这是目前绝大多数教学资料和公司的生产版本不要用太高版本因为部分教程依赖的第三方库对新版本支持有坑Spring Boot 2.x版本别太新也别太旧2.52.7这个区间比较好MyBatis-Plus这个强烈推荐。它既保留了MyBatis的SQL灵活性又内置了通用的单表CRUD方法能省掉大量重复的Mapper代码MySQL 5.7或8.0都是主流版本5.7更稳定8.0性能更强、自带窗口函数选哪个都行JWT做登录鉴权无状态、跨域友好很适合前后端分离这种纯接口交互的模式注意很多新手会纠结“要不要用Spring Cloud微服务”我的建议是不要用。毕业设计要的是“麻雀虽小五脏俱全”你在单体应用里把分层做好远比把一个模块拆成三个服务更符合本科论文的预期。微服务是加分项但只是在你基础功能全部完成之后、有大量剩余时间的前提下才考虑。DB层面除了字段类型、约束设计我强烈建议用MyBatis-Plus的代码生成器AutoGenerator自动生成实体类、Mapper接口、Service、Controller全链路代码。你只需要配置好数据库连接和表名一键生成再在生成代码的基础上做修改和优化。这样做的几个好处是省去大量重复的手写CRUD时间生成代码的规范统一投稿到GitHub或者放答辩PPT上都显得专业你可以在生成代码的基础上把精力集中到核心业务审批流程、薪资计算的打磨上2.3 前端技术选型与页面组件化前端我建议使用Vue 2.7不是Vue 3原因很简单你搜资料用的绝大多数博客、案例、组件库的文档都是基于Vue 2的用Vue 3会面临部分第三方组件不兼容的麻烦。再加上Element UI这个组件库表格、表单、弹窗、分页这类管理系统的“常客”组件都能开箱即用你不需要从零手写一个分页器。前端的核心技术点是“页面组件化”。你要把重复出现的结构抽成通用组件。比如员工列表和部门列表的查询表格长得非常像那你就可以抽一个SearchTable组件父组件只负责传入搜索字段配置和表格列配置子组件负责渲染搜索区、调用接口、分页交互。这样一来新增一个功能页面的时候只需要写配置不需要复制粘贴一大堆HTML模板。这个点写进论文的“系统实现”章节会非常出彩因为它体现了组件化设计思想。前端的另一个重点是路由和权限的配合。实现方案如下用户登录成功后后端返回一个角色标识比如role: admin和一组可访问的路由表数据前端在路由守卫中判断用户访问的路径是否在权限列表内不在就重定向到403页面菜单也根据权限动态生成没权限的菜单压根不显示这套方案做下来你的权限控制从前端展示到后端校验就形成一个闭环论文里至少有三千字的素材可以写。2.4 为什么不用更简单或更复杂的方案有人可能会问直接用JSPServlet不更简单吗是代码量可能更少但你做毕业设计不只是为了“交差”导师很可能会问“为什么不用当前主流的框架技术”你用JSP回答很难自圆其说。反过来问为什么不用微服务、分布式答案也很简单项目规模不需要单体架构完全能承载过度设计反而是负担。用Spring Boot Vue的核心优势在于“主流”二字。这里的主流体现在招聘市场上这类岗位需求量最大写进简历有实际价值社区资料丰富你遇到任何问题搜索一下都有答案技术栈本身风格清爽不会因为复杂配置耗尽你的时间3. 核心功能设计——从需求到落地的完整拆解3.1 角色划分与权限模型人事管理系统先要搞清楚“谁在用”这决定了你整个系统的功能边界。我建议划分为三种角色系统管理员拥有全部权限比如新增员工、删除员工、分配账号角色、查看操作日志人事专员HR可以操作用户管理相关业务但不能做系统级配置比如修改薪资标准、审批请假普通员工只能操作个人相关信息比如查看自己的考勤记录、提交请假申请、查看工资条前端的路由权限依据这个划分来控制“能访问哪些菜单”后端的拦截器依据这个划分控制“能调用哪些接口”。两边都做而不是只做前端这是很多同学容易忽略的点。这里我建议用经典的RBAC基于角色的访问控制模型数据库设计五张核心表用户表user、角色表role、菜单权限表menu、用户角色关联表user_role、角色菜单关联表role_menu。不需要引入更复杂的ABAC基于属性的权限控制用了反而显得你不理解业务和技术的匹配关系。3.2 核心业务模块清单一张表格直接看懂整个系统该有哪些模块模块核心功能关键表难度评估员工管理员工信息增删改查、条件筛选、导入导出employee、dept简单部门管理部门树形结构、部门负责人设置、部门转调dept中等考勤管理上下班打卡记录、考勤统计、异常处理attendance中等薪资管理薪资结构配置、月度薪资计算、工资条查看salary、salary_detail较难请假管理请假申请、多级审批、销假处理leave、audit_record较难招聘管理岗位发布、简历投递、面试结果登记position、resume中等系统管理用户管理、角色管理、菜单管理、操作日志user、role、log中等越往下的模块越能体现你的设计深度。比如“薪资管理”里你可以把薪资计算做成一个“模板”概念基础工资 岗位津贴 绩效系数 - 五险一金 - 考勤扣款每个员工对应一个计算模板月底系统自动按模板批量计算。这个逻辑不算复杂但论文里可以把推导过程写得非常丰富。3.3 数据库设计的关键原则数据库设计是我在评审时最关注的部分之一。设计好的人事系统数据库表和表的关系清晰字段命名统一冗余可控。我总结几个实操原则第一主键一律用自增ID不要用自然主键不要用UUID做主键除非你有分布式场景。这一点在答辩时经常被问到自增ID在InnoDB引擎下索引效率更高也更符合常规管理系统的设计习惯。第二凡是多对多关系都必须建中间表。比如用户和角色是多对多就建user_role角色和菜单是多对多就建role_menu。第三逻辑删除大于物理删除。员工离职不等于从系统里消失你得在员工表加一个status字段0表示在职1表示离职1表示禁用可以再加一个状态。同理部门的解散也是改状态而不是直接删行。这个习惯能保证历史数据可追溯也是企业开发的通用做法。第四冗余字段要有度。比如员工表里存一个部门名称的冗余字段就可以避免每次查询都关联部门表。但是冗余一多就会带来数据一致性问题我的建议是只在“查询频繁、更新极少”的字段上做冗余典型如员工表的部门名称、薪资表的员工姓名这类字段一年也改不了几次。3.4 接口设计规范与状态码体系后端写接口不是把数据返回就结束了你需要有一套全局统一的规范。我在项目中是这样设计的所有Controller返回统一体Result结构为{ code: 200, message: 操作成功, data: { ... } }定义请求成功的code为200参数错误为400未登录或登录失效为401无权限为403服务器异常为500分页查询统一返回PageResult包含records、total、current、size四个字段划重点登录失效判断是很多答辩小组会问的点。你要能说清楚前端在Axios响应拦截器里判断HTTP状态码或业务code如果返回401就清掉本地Token跳转到登录页。这也是为什么我们使用JWT而不是Session——JWT无状态后端不存会话校验通过即信任Session需要后端维护状态前后端分离时还要考虑跨域请求携带Cookie的复杂问题。4. 从零搭建系统的实操过程记录4.1 后端初始化与基础配置第一步打开Spring Initializr生成基础工程。选Java 8、Spring Web、MySQL Driver这几个依赖然后手动把MyBatis-Plus和JWT相关依赖加进pom.xml。这里有一个非常容易踩的坑Spring Boot的版本和MyBatis-Plus的版本兼容问题。如果你用Spring Boot 2.7以上MyBatis-Plus尽量用3.5.x系列否则启动时可能出现Mapper扫描异常。建议直接采用当前时间最新的稳定组合并在pom中明确写好version不要用不加版本号的方式依赖传递。第二步配置application.ymlserver: port: 8080 servlet: context-path: /api spring: datasource: url: jdbc:mysql://localhost:3306/hr_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl关于日志配置我要提醒一下log-impl改成StdOutImpl后你在控制台可以看到每条SQL的实际执行语句排查问题非常方便。答辩演示时还可以故意查询一条数据指着控制台展示SQL日志这比纯口头讲数据库设计有说服力得多。第三步实现全局异常处理和统一响应体。我建了一个GlobalExceptionHandler用RestControllerAdvice注解拦截所有异常分类返回不同code。比如自定义BusinessException返回400并携带具体错误信息否则一律返回500。没有这一步你后端的任何一个小报错都会直接以500的形式暴露给前端调试起来非常痛苦。4.2 核心接口开发实战——以员工模块为例员工管理是最典型的一块业务我以这个模块为例带你完整走一遍后端到前端的实现链路。数据库表employee的关键字段设计CREATE TABLE employee ( id bigint(20) NOT NULL AUTO_INCREMENT, emp_no varchar(32) NOT NULL COMMENT 员工工号, name varchar(64) NOT NULL COMMENT 姓名, gender tinyint(4) DEFAULT NULL COMMENT 性别 1男 0女, dept_id bigint(20) DEFAULT NULL COMMENT 部门ID, position varchar(64) DEFAULT NULL COMMENT 岗位, phone varchar(20) DEFAULT NULL, email varchar(128) DEFAULT NULL, entry_date date DEFAULT NULL COMMENT 入职日期, status tinyint(4) DEFAULT 0 COMMENT 0在职 1离职, create_time datetime DEFAULT NULL, update_time datetime DEFAULT NULL, PRIMARY KEY (id), KEY idx_dept_id (dept_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;对应的查询接口GET /employee/list需要支持按姓名、部门、状态、入职日期范围查询并返回分页结果。这个接口用MyBatis-Plus的分页插件实现只需要不到十行核心代码但查询条件的组织逻辑值得写细Override public PageResultEmployeeVO pageEmp(EmployeeQuery query) { LambdaQueryWrapperEmployee wrapper new LambdaQueryWrapper(); // 关键字模糊查询非空判断 wrapper.like(StringUtils.hasText(query.getName()), Employee::getName, query.getName()) .eq(query.getDeptId() ! null, Employee::getDeptId, query.getDeptId()) .eq(query.getStatus() ! null, Employee::getStatus, query.getStatus()) .ge(query.getStartDate() ! null, Employee::getEntryDate, query.getStartDate()) .le(query.getEndDate() ! null, Employee::getEntryDate, query.getEndDate()) .orderByDesc(Employee::getCreateTime); return pageQuery(wrapper); }这里的重点不是代码写法而是“条件判断放进构造查询条件”这个思想。写死几个查询条件很容易但你得让你的论文评阅人能理解你如何实现“多条件组合查询时不产生多余SQL”。前端员工列表页则对应几个关键步骤页面加载时调用接口把返回数据渲染到Element UI的表格组件搜索按钮触发带查询参数的请求新增和编辑共用一个弹窗表单提交时区分为POST和PUT两个接口。如果你想让这个模块更有亮点可以顺手加上“员工信息Excel导入导出”。用EasyExcel这个阿里开源工具几十行代码就能实现批量导入校验和导出下载。这不仅是论文里非常好的一个实现亮点答辩时也容易引导老师关注“你怎么处理了大数据量导入的校验问题”你可以自信回答“按行读取、逐行校验不符合规则的生成错误汇总信息”。4.3 前端权限控制与动态路由实现前端部分最值得详细写的功能我建议重点做“动态路由”。它解决的核心问题是不同用户登录后看到的菜单不一样访问的页面也不一样。实现逻辑不复杂我在这直接把核心流程拆开用户登录成功后端返回Token前端存到localStorage前端携带Token调用GET /auth/info获取用户信息和可访问的路由权限数据拿到权限数据后用Vue Router的addRoutes方法动态注册对应路由路由守卫里判断如果访问路径不在权限列表则跳转到403页面侧边栏菜单根据路由表自动生成子菜单不需要单独再写菜单配置这里有一个坑就是刷新页面时路由会重置。你必须把路由数据同步存储到Vuex或者sessionStorage刷新之后重新拉取或读取存储恢复。很多同学第一次做动态路由时都卡在这一步我建议你在store里维护一个menus数组刷新时先判断store是否有数据没有则请求接口恢复。4.4 考勤与审批流的设计心得如果一个同学能写清楚考勤审批流程的实现我会给这个项目的技术分一个额外加分。因为审批流本质上是一个有限状态自动机的应用。请假模块我建议这样设计请假单表leave增加status字段0为待审批1为审批通过2为审批驳回3为已撤销。提交申请时生成一条audit_record记录申请内容、申请时间、当前审批人审批人处理时再生成一条新记录并修改状态。这样一来整个审批链路就可以追溯。有人会说这不就是“改个状态”吗对但改状态背后的设计是状态机哪些状态能流转到哪些状态哪些角色在哪个状态下可以执行哪个操作这说起来简单做的时候很容易遗漏边界。比如“审批驳回后员工能不能再次编辑请假单”如果你的状态机设计不好这条分支就体现不出来。我在项目里用一张状态流转表把所有合法路径写清楚并进行了注释说明。论文里我建议也放一张表格把“状态、操作、前置状态、目标状态、操作角色”列清楚。这种设计感和规范性比堆砌功能代码更能体现你的系统设计功底。5. 论文写作——从功能描述到系统设计的进阶5.1 论文框架与章节布局毕业论文的章节结构是有“标准答案”的。我建议你遵循传统软件工程类论文的框架不要在结构上搞创新第1章 绪论研究背景与意义、国内外研究现状、主要研究内容第2章 相关技术介绍Spring Boot、Vue、MySQL、MyBatis-Plus简单介绍核心原理即可第3章 系统需求分析可行性分析、功能需求、非功能需求、用例图第4章 系统设计总体架构、功能模块设计、数据库设计E-R图、数据表结构第5章 系统实现核心功能的具体实现、界面截图、关键代码第6章 系统测试测试环境、功能测试用例、测试结果分析第7章 总结与展望这个框架最大优势是“稳”符合大多数导师的预期你不需要在结构上冒险。真正拉开差距的地方在于你的内容密度第3章需求分析是不是给出了完整的用例图和用例描述第4章数据库设计是不是有完整的POWERDESIGNER或PDMan导出的物理模型第5章实现是不是做到每个核心功能都有界面图、核心代码、文字说明三件套5.2 技术预研怎么写才不空洞“相关技术介绍”这一章几乎人人都写但九成学生写成了教科书摘抄Spring Boot是个快速开发框架Vue是渐进式JavaScript框架……全是废话。换个思路你不能光介绍技术“是什么”要突出“为什么在本次开发中选择它”。比如Spring Boot我选它的原因是“约定大于配置”——内嵌Tomcat、自动装配、起步依赖三件事让项目搭建时间从小时级降低到分钟级Vue我选它的原因是“组件化响应式”——开发效率高尤其是Element UI可以让我把精力从重复的表单组件中解放出来专注业务逻辑MyBatis-Plus我选它的原因是“兼顾灵活与效率”——复杂SQL我用Mapper XML手写单表CRUD直接用内置方法代码量比纯MyBatis少三分之一以上这样写导师一眼就能看出你是真正用过这些技术而不是复制粘贴博客。5.3 论文图表规范与加分细节论文里图表的重要性我怎样强调都不为过。系统架构图、功能结构图、E-R图、数据库表结构图、流程图这五个图是你必须画到“干净规范”程度的。用Visio或Draw.io画图注意以下几点系统架构图不要画成“三层套娃”要体现前端服务器、后端服务器、数据库服务器的物理分区功能结构图用树形结构每个叶子节点对应一个明确功能点E-R图必须标注主外键关系菱形或关系线要清晰实体类比如Employee类的关键字段、数据库字段、前端页面上的字段三者名称要一一对应不要出现英文名和中文名对不上的情况最后不要忘了在绪论里写上“本文的组织结构”这一小节逐章简要说明全文脉络。这是很多同学容易漏掉、但导师几乎必看的部分。6. 开发与答辩过程中的高频问题速查6.1 开发阶段最常踩的十个坑我把过去几年带过的学生以及我自己当年在开发这种系统时最高频踩的坑整理一下跨域请求失败前端端口比如8081与后端端口8080不一致必须配置Cors跨域或者在Spring Boot里加CrossOrigin或者用网关转发。其实更推荐用前端Vite/Webpack的代理配置生产环境才用Nginx统一解决中文乱码MySQL连接URL忘记带characterEncodingutf8或者建表时用的不是utf8mb4字符集JWT过期后前端没有正确处理401导致一直白屏没有提示MyBatis-Plus的updateById空字段不更新默认策略是忽略null字段想强制更新要用UpdateWrapper的.set分页总数查不出来分页插件拦截器没有配置或者返回类型用错了List而不是IPage删除部门时外键冲突没有做“部门下是否有员工”的校验就直接删数据库报错前端找不到后端接口接口路径写错、大小写不匹配建议所有接口都统一用小写和中划线日期格式化问题后端返回LocalDateTime默认是ISO格式前端显示不友好要配置JSON序列化的日期格式刷新后404Vue Router使用history模式时刷新页面会404解决方案是后端做fallback到index.html或改用hash模式测试数据太少答辩时演示员工列表只有三条数据显得很单薄。用脚本批量生成两三百条演示数据列表分页效果立马真实起来6.2 答辩时容易被追问的尖锐问题毕业设计答辩最怕的不是系统出bug而是“你做了但没有想清楚”。我每年都会听到评委老师反复追问下面几个问题提前准备好答案问为什么用JWT而不用传统的Session答因为JWT是服务端无状态的适合前后端分离和水平扩展的场景。Session需要服务端保存会话一旦部署多台服务器就要引入会话共享方案复杂度高。JWT把校验信息放在客户端Token里服务端只负责验签更符合当前微服务和前后端分离的主流架构。问如何处理密码安全答密码不存储明文使用BCrypt加密存储Spring Security自带BCryptPasswordEncoder每次登录校验加密后的密文是否匹配。即使是数据库泄露攻击者也拿不到明文密码。问系统的性能瓶颈在哪里答人事系统的数据量级一般不大瓶颈更多在查询效率和报表生成上。比如一个月度考勤统计涉及几千上万人次的考勤记录如果没有合理索引查询会很慢。我通过为时间字段和部门字段建立联合索引、对统计类数据使用定时任务预聚合把单次查询从秒级下降到毫秒级。问数据库设计的第三范式你在哪里做了妥协答我在员工表中冗余存储了部门名称。虽然这违反了第三范式但在人事系统中部门名称变更频率极低而按部门名称筛选员工的操作频率极高加这一列能明显减少关联查询。这是为性能做的合理“反范式”设计。问如果系统要支持一万人在线使用你觉得哪些环节需要改造答需要升级的点包括数据库方面做读写分离或引入Redis缓存热点数据登录接口加限流和验证码机制防止暴力破解静态资源前端构建产物放到对象存储或CDN后端按模块拆分成可水平扩展的独立服务新增操作日志的异步落库机制避免高峰期写日志影响主流程性能。6.3 最终演示的准备工作我想郑重地说你的答辩印象分很多时候是从你打开演示页面那一刻就开始计算的。三个细节务必提前做演示环境不要用localhost看起来特别随便用自定义域名比如hr.demo.com映射到本机hosts再用Nginx把前后端请求分别反代到对应端口打开页面地址栏显示的是正式域名档次感立刻不一样提前准备好“演示脚本”按以下顺序走登录演示权限控制→ 员工管理演示增删改查导入导出→ 请假审批演示多角色状态流转→ 薪资模块演示计算结果→ 系统管理演示创建新角色并分配权限演示过程中预计网络或服务可能中断先把后端程序打包好、MySQL服务确认是开机自启准备一个“一键启动脚本”防止关键时刻露怯7. 实践经验深度总结做这个毕业设计我最大的体会是人事管理系统真正难的不是技术而是“用工程化思维方式处理业务”。很多同学一开始上手就写代码写到哪里算哪里数据库表结构边写边改最终靠加班补窟窿。而正确的做法应当是先做需求分析画出用例图理清角色和权限关系设计好数据库表之后再动代码。前期多花三天后期至少能少返工两周。还有一个很实用的心得是尽量让代码比论文先写完。因为论文里的截图、流程图、核心代码、测试用例表全部需要以真实运行为底稿。先有了跑通的系统论文的每一张图、每一个数据都有依据不会出现“论文里写的功能实际演示时找不到”的尴尬。最后再分享一个让系统看起来“有企业级质感”的小技巧全局异常处理里加一个统一的操作日志切面用Spring AOP拦截所有Controller请求记录哪个用户在什么时间做了什么操作。答辩时你可以在系统里随便点几下然后打开日志管理页面手动指着那条新产生的记录讲“这就是我对系统可追踪性的设计实现”。这一句话的含金量比你说二十句“我增强了系统的安全性”都有说服力。