
简介本资源是一套面向计算机专业本科生的毕业设计完整交付包聚焦中小企业人事管理场景解决传统人工管理效率低、信息分散、权限混乱等实际问题。包内含427个文件总大小37.76MB涵盖114个Java后端核心代码、44个Vue前端组件、21个XML配置及SQL数据库脚本等关键资产完整支撑SpringBootVueMySQL技术栈的前后端分离开发实践同时包含毕业论文、答辩PPT、系统部署说明及2个MP4演示视频覆盖从环境搭建、功能实现到答辩汇报的全流程。内容预览可见多个.bat一键脚本如install/run/build、Vue组件备份文件及CSS/JS构建产物体现工程化规范与可复现性。目前已有158人学习下载适合需快速上手毕设开发、理解权限控制、考勤工资模块设计及前后端联调逻辑的学习者。 毕业设计做人事管理系统算是Java全栈里最经典的一类题目了。SpringBoot Vue MySQL这个组合无论是从工作量、技术难度还是答辩时的讲稿深度来看都非常适合作为本科毕设的选题。它不像电商系统那么复杂也不像简单的图书管理那样显得单薄正好卡在一个“该有的都有、但不至于收不住”的平衡点上。这篇内容我打算直接拿“中小企业人事管理系统”这个项目来做一次完整复盘从技术选型逻辑、数据库设计、后端接口实现、前端页面联调一直聊到论文怎么写、答辩视频怎么录。如果你正在做或者准备做类似的题目这篇文章应该能帮你省下不少瞎琢磨的时间。1. 项目整体设计与技术选型思路1.1 为什么是SpringBoot Vue MySQL这个组合先聊技术选型。很多同学纠结要不要用更“新”的技术比如微服务、Redis、MQ之类的。我的建议很直接本科毕业设计除非题目明确要求否则不要主动引入分布式那一套。原因很简单评委老师看的是你对一个完整业务系统的理解和实现能力而不是技术名词堆砌。引入微服务意味着你要额外解释服务拆分、注册中心、配置中心任何一个环节讲不清反而减分。SpringBoot Vue MySQL这套组合的优势在于SpringBoot大幅简化了SSM时代的配置流程内置Tomcat打jar包就能跑让开发者的注意力集中在业务逻辑上。这也是目前企业里中小型项目的主流姿势。Vue作为前端渐进式框架组件化开发思路清晰配合Element UI现在更多用Element Plus能快速搭出后台管理界面开发效率和展示效果都很好。MySQL是关系型数据库里最普及的方案对于人事管理这种以结构化数据为主的场景性能、稳定性和生态支持都完全够用。一句话总结这个组合是“行业标准答案”你不需要说服评委它有多先进你只需要说清楚它为什么适合这个场景——开发效率高、生态成熟、学习成本适中、资料多。1.2 人事管理系统的核心业务模块拆解在动手写代码之前一定要把业务模块想清楚。人事管理系统表面上看是“增删改查”但真正设计的时候需要拆出边界。我当时把系统拆成了这几个核心模块系统管理用户登录、验证码、JWT鉴权、菜单权限、角色管理。这是很多系统的地基也是答辩时老师比较关注的部分。部门管理企业组织架构维护需要支持树形结构比如总公司-分公司-部门-小组。员工管理核心业务包括员工基本信息、入职时间、职位、学历、联系方式、紧急联系人等。考勤管理记录每日打卡时间、迟到早退、请假审批、加班申请。工资管理根据基本工资、岗位工资、考勤扣款、加班费、社保扣除等计算实发薪资。公告管理企业发布通知支持置顶、过期自动下线。为什么要拆清楚因为数据库表的设计、后端接口的划分、前端页面的组织都依赖于这个模块边界。模块边界画清楚了后面的工作量其实是线性展开的不会出现“写着写着不知道代码该放哪个包”的问题。我当时犯过一个比较典型的错误一开始只设计了一张员工表做了员工增删改查页面就去写论文了。后来导师说考勤和薪资不能没有结果又回头加表、加字段、加关联前后端代码改了好几版。所以我的建议是无论你的开题报告里写了多少功能数据库设计阶段务必一次想清楚不然后面的返工成本极高。2. 数据库设计一张好表胜过十次重构2.1 核心表结构设计要点数据库是整个系统的地基表关系设计得好不好直接决定接口写起来顺不顺。我用的表结构大概是这样设计出来的供你参考。员工表employee这是系统的核心数据表。关键字段包括工号、姓名、性别、出生日期、身份证号、手机号、邮箱、部门ID、职位、入职日期、学历、政治面貌、家庭住址、紧急联系人、紧急联系电话、状态试用/在职/离职、创建时间、更新时间。身份证号、手机号这种字段建议用varchar不要用bigint因为前端展示时可能会丢失精度或者需要格式化手机号如果是bigint也会有问题因为超过一定长度会溢出或用科学计数法显示。部门表department部门表需要支持树形结构所以除了部门ID、名称、负责人、联系电话之外还必须加parent_id字段。这里有个细节root节点的parent_id设为0或者NULL然后通过后端递归组装成树形结构返回给前端。考勤表attendance字段包括ID、员工ID、日期、上班打卡时间、下班打卡时间、上班状态正常/迟到/未打卡、下班状态正常/早退/未打卡、加班时长。需要注意的唯一约束是(employee_id, date)同一个员工同一天只能有一条考勤记录。我当时没有加这个唯一索引测试的时候用重复数据插入结果同一个员工一天出现了三条考勤记录页面表格直接乱了。加上唯一索引之后配合INSERT ... ON DUPLICATE KEY UPDATE或者先查后改问题就解决了。请假表leave字段包括ID、员工ID、请假类型事假/病假/年假/调休、开始时间、结束时间、请假天数、请假事由、审批状态待审批/通过/驳回、审批人、审批时间。工资表salary字段包括ID、员工ID、工资月份如2025-06、基本工资、岗位工资、绩效工资、加班费、迟到扣款、请假扣款、社保扣款、公积金扣款、实发工资。唯一约束(employee_id, month)。2.2 建表时的避坑经验建表的时候有几点需要特别注意统一使用InnoDB引擎utf8mb4字符集。utf8mb4兼容emoji和生僻字现在基本是标配。主键都设计成自增的bigint不推荐用UUID做主键因为无序会严重影响InnoDB索引性能。所有业务表都要有create_time和update_time这两个字段看似不起眼但写论文的“系统设计”章节时很加分而且排查线上问题也靠它们。逻辑删除和物理删除要想清楚。我建议所有业务表都加一个deleted字段0未删除1已删除。员工如果被误删数据找不回来会非常麻烦。使用逻辑删除之后需要注意的是所有查询接口都要默认带deleted 0条件。MyBatis-Plus里有TableLogic注解可以自动处理这个逻辑。金额字段用decimal(10,2)比如工资。不要用float或者double浮点数计算会有精度问题这在涉及钱的场景是不能接受的。数据库设计是我个人认为整个项目里最值得多花时间的地方因为后续所有接口、所有页面都依附于表结构。我自己的习惯是先用draw.io或processon.com画ER图再对着ER图建表。画图的过程其实就是把关系理清楚的过程。3. SpringBoot后端核心实现细节3.1 项目初始化和基础配置后端的项目结构我建议按照功能模块分包而不是按照技术类型分包。比如com.example.hrms ├── config # 配置类MyBatis-Plus、跨域、拦截器 ├── controller # 控制层 ├── service # 业务层接口实现 ├── mapper # MyBatis-Plus的Mapper接口 ├── entity # 实体类 ├── dto # 请求/响应对象 ├── common # 公共类统一返回结果、异常处理 └── utils # 工具类JWT工具、日期工具SpringBoot的版本选择上推荐SpringBoot 2.7.x搭配JDK 1.8。可能有人觉得应该直接上3.x但3.x最低要求JDK 17而且很多教程和依赖还不完全兼容对于毕设来说2.7.x是最稳妥的选择。application.yml里的几个关键配置server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/hrms?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver servlet: multipart: max-file-size: 10MB max-request-size: 10MB mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 jwt: secret: your-secret-key expire: 604800这里要特别提醒一个坑数据库连接的URL里必须加上serverTimezoneAsia/Shanghai否则高版本的MySQL驱动会报时区错误。另外字符集一定要带上不然中文插入进去就是乱码。3.2 登录鉴权与权限拦截登录模块是每个系统都绕不开的这部分也是最容易被老师在答辩时追问的。我采用的是JWTJSON Web Token方案。流程是这样的用户提交用户名密码后端校验通过后生成一个token返回给前端前端把token存在localStorage里每次请求都在请求头里带Authorization: Bearer token后端写一个拦截器拦截需要登录的接口校验token是否有效。JWT工具类核心代码大概长这样public class JwtUtil { private static final String SECRET your-secret-key; private static final long EXPIRE 604800000L; // 7天 public static String generateToken(Integer userId, String username) { return Jwts.builder() .setSubject(username) .claim(userId, userId) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() EXPIRE)) .signWith(SignatureAlgorithm.HS256, SECRET) .compact(); } public static Claims parseToken(String token) { return Jwts.parser() .setSigningKey(SECRET) .parseClaimsJws(token) .getBody(); } }拦截器的写法这里就不贴完整代码了核心逻辑就是在preHandle方法里检查请求头是否携带token如果token解析失败就返回401状态码。有两个细节需要注意放行登录接口和验证码接口不然用户还没登录就被拦截了死循环。跨域问题必须处理。前端Vue跑在8081端口后端跑在8080端口跨域是必然的。我用的方案是写一个CorsConfig配置类或者用CrossOrigin注解。如果不处理跨域前端所有请求都会被浏览器拦截控制台会报CORS policy错误。关于权限控制建议用最简单的方案用户表里加一个role字段admin/user管理员可以看到系统管理菜单普通员工只能看到自己的信息。用拦截器判断角色即可。如果做基于RBAC的完整权限模型工作量会翻倍对于毕设来说不是必须的。当然如果你想让论文更有内容可以在系统设计章节里专门写一节“基于RBAC的权限模型设计”但代码实现用简单的角色判断就够了论文内容和代码实现之间不需要完全对等。3.3 部门树与员工管理接口设计部门树接口是我认为后端里比较有代表性的一个接口。它的核心逻辑是查出所有部门然后在内存中递归组装成树形结构。public ListDepartmentVO buildTree() { ListDepartment allDepartments departmentMapper.selectList(null); MapInteger, DepartmentVO map new HashMap(); ListDepartmentVO roots new ArrayList(); for (Department dept : allDepartments) { DepartmentVO vo new DepartmentVO(); BeanUtils.copyProperties(dept, vo); vo.setChildren(new ArrayList()); map.put(dept.getId(), vo); } for (Department dept : allDepartments) { DepartmentVO vo map.get(dept.getId()); if (dept.getParentId() 0) { roots.add(vo); } else { DepartmentVO parent map.get(dept.getParentId()); if (parent ! null) { parent.getChildren().add(vo); } } } return roots; }员工管理接口的设计相对直接核心是EmployeeController提供分页查询、添加、修改、删除、导出等接口。这里有一个比较实用的经验分页查询不要只查employee表本身还要关联出部门名称和职位名称不然前端表格里显示的只是一个数字ID用户根本看不懂。我用的方案是写一个VO类EmployeeVO在Service层做数据组装通过MyBatis-Plus的分页插件配合自定义SQL完成关联查询。工资计算是一个值得在论文里好好写的业务点。工资计算规则包括基本工资岗位工资绩效工资加班费-迟到扣款-请假扣款-社保-公积金。其中迟到扣款是考勤数据联动的请假扣款是请假数据联动的。这部分业务逻辑比单纯增删改查有深度写进论文里会让导师觉得这个项目不是纯CRUD。4. Vue前端页面与接口对接实操4.1 前端工程初始化和路由设计前端我使用的是Vue 2 Element UI。这是个很成熟经典的组合网上资料极多遇到问题几乎都能搜到解决方案。Vue 3 Element Plus当然也可以但很多旧教程都对不上调试起来更费时间。对于毕设我的原则依然是“求稳”。用Vue CLI创建项目vue create hrms-web创建完成后安装依赖npm install element-ui axios vue-router vuexVue Router我用的路由模式是history路由配置大概长这样const routes [ { path: /login, component: Login, hidden: true }, { path: /, component: Layout, redirect: /dashboard, children: [ { path: dashboard, name: 首页, component: Dashboard }, { path: employee, name: 员工管理, component: Employee }, { path: department, name: 部门管理, component: Department }, { path: attendance, name: 考勤管理, component: Attendance }, { path: salary, name: 工资管理, component: Salary }, { path: leave, name: 请假管理, component: Leave }, { path: notice, name: 公告管理, component: Notice } ] } ]这里要注意的一个坑是history模式下刷新页面时如果后端没有做统一转发会出现404。解决办法有两个一是后端写一个Controller转发到index.html二是改用hash模式。如果为了图省事hash模式更稳URL上虽然多个#但对于毕设展示完全没影响。4.2 Axios封装和路由守卫Axios请求封装是前端联调的关键。如果不做统一封装每个页面都要写一遍axios.get 错误处理代码会很啰嗦。我习惯在utils/request.js里做一个统一的axios实例import axios from axios const request axios.create({ baseURL: /api, timeout: 10000 }) request.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization Bearer token } return config }) request.interceptors.response.use( response { const res response.data if (res.code 200) { return res } else { this.$message.error(res.msg || 请求失败) return Promise.reject(new Error(res.msg)) } }, error { if (error.response error.response.status 401) { localStorage.removeItem(token) router.push(/login) } return Promise.reject(error) } ) export default request这里设计了一个统一返回格式{ code: 200, msg: success, data: ... }。后端所有接口都返回这个结构前端拿到之后统一处理逻辑会非常清爽。这个后端可以写一个Result类来统一响应格式。路由守卫的作用是未登录状态不能访问首页已登录状态不能访问登录页。router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.path /login) { next() } else { if (token) { next() } else { next(/login) } } })4.3 页面组件和联调时最常见的坑前端页面我用的是Element UI的el-table、el-form、el-dialog、el-tree这几个核心组件。员工管理页面最典型的交互是表格展示 搜索栏 弹窗表单 删除确认。一个Excel导出功能可以大大提升系统的完整度答辩演示时也比较亮眼。前端可以调用后端接口直接下载window.open(/api/employee/export, _blank)不过在下载的时候需要处理一下请求头中的token否则会被拦截器拦住。更好的做法是用axios设置responseType: blob拿到Blob数据后用URL.createObjectURL生成下载链接。联调时最容易踩的坑有这几个第一个坑跨域请求失败。这个前面说过了后端配置CorsConfig即可解决。注意要配置allowedOriginPatterns不要用allowedOrigins(*)高版本SpringBoot会报错。第二个坑日期格式化。Java端的LocalDate序列化到前端默认是一串数组[2025, 6, 1]非常难看。解决办法是在配置里加一个Jackson的日期格式化配置Configuration public class JacksonConfig { Bean public Jackson2ObjectMapperBuilderCustomizer customizer() { return builder - { builder.serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(yyyy-MM-dd))); builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss))); }; } }第三个坑Element UI表格的prop名要和后端返回的字段名一致。如果你在Java里把字段命名为employeeName前端写的就是employeeName千万不要图省事在SQL里写别名。不一致的话表格里会一直显示空值排查半天发现是字段名对不上。第四个坑Vue项目的proxy配置。在开发环境下我更推荐在vue.config.js里配置代理而不是用后端的CorsConfig。通过devServer.proxy把/api开头的请求转发到http://localhost:8080这样前端代码里看起来就是同源的跨域问题从根本上规避了。不过要注意部署到服务器上的时候还是得处理跨域所以后端CorsConfig还是要保留。5. 毕业论文与答辩视频准备5.1 论文结构怎么安排论文是毕业设计的重头戏。我见过太多代码写得不错、论文一塌糊涂的例子最后分数反而不如代码一般但论文写得清楚的。论文的核心思路是先讲背景和意义再讲需求分析然后讲系统设计最后展示实现效果。一个比较标准的章节结构是这样的第一章 绪论研究背景、研究意义、国内外研究现状、本文的主要工作。这一章要在知网上找几篇相关的参考文献引用到“国内外研究现状”里。第二章 相关技术介绍SpringBoot框架、Vue框架、MySQL数据库、JWT认证机制。注意不要写成纯名词解释要结合项目说为什么选它。第三章 系统分析可行性分析技术可行性、经济可行性、操作可行性、功能需求分析、非功能需求分析。可以画用例图用Rational Rose或PlantUML都行。第四章 系统设计系统架构设计、功能模块设计、数据库设计ER图 主要表结构说明、接口设计。这里是论文的核心章节字数占比最大。第五章 系统实现每个模块的实现截图 核心代码片段 实现说明。注意核心代码不要贴太多一般不超过10行关键是讲清楚逻辑。第六章 系统测试功能测试用例表用例编号、测试步骤、预期结果、实际结果、是否通过、性能测试简述、测试结论。第七章 总结与展望总结项目成果展望下一步可以引入技术。每一章的字数要有意识地分配。很多同学前两章写到飞起到后面实现和测试章节反而没话了。我个人的建议是相关技术介绍控制在2000字左右系统分析和系统设计是重点要写到5000字以上系统实现2000-3000字系统测试1500字左右。总字数在1.2万到1.5万字之间比较合适。数据库设计章节里一定要放ER图。不会画ER图可以用draw.io或者PowerDesigner画完导出图片贴到论文里。表结构说明列个表格每个字段一行标注字段名、类型、是否为空、说明。这部分能有效提升论文的专业感。5.2 答辩PPT与演示视频录制技巧答辩PPT建议控制在15-20页时间控制在10分钟左右。内容结构选题背景与意义2页、技术栈介绍2页、系统功能结构2页、数据库设计2页、核心功能展示5-6页、系统测试总结2页、致谢1页。展示核心功能时不要上来就点鼠标乱逛。要有主线比如登录系统 - 进入首页看统计 - 新增一个员工 - 给这个员工添加一条考勤记录 - 查看工资计算。让老师顺着你的操作知道你每一步在干什么。视频演示一般是用录屏软件OBS、EV录屏等录制。录制前务必做一次完整的走读把鼠标移动的路径都记在心里。录制时注意以下几点分辨率建议1920x1080视频画面要清晰不要在录屏的时候同时开一堆无关窗口。声音清晰语速适中。即使你平时说话很快录制时也要刻意放慢。演示顺序和PPT保持一致老师看起来会比较舒服。时长控制在15-30分钟太短了显得内容少太长了老师看不完。遇到意外情况比如页面报错先保持冷静可以解释这是“故意演示异常处理流程”往往能化险为夷。当然如果错误太明显建议重录。还有一个容易被忽略的地方视频演示里最好包含源码结构和数据库脚本的运行过程。你可以展示一下Navicat里导入SQL脚本、后端项目启动、前端项目启动的完整流程这会让老师觉得整个项目是你自己真正做出来的而不是下载了别人的源码改了个标题。6. 常见问题排查与经验速查6.1 环境与启动问题问题1后端启动时报端口被占用这是最常遇到的问题之一。解决办法找到占用8080端口的进程并杀掉或者修改application.yml里的server.port。Windows下查看端口占用netstat -ano | findstr 8080 taskkill /pid [进程ID] /f问题2Maven依赖下载失败或版本冲突建议使用阿里云镜像在~/.m2/settings.xml的mirrors节点里配置阿里云仓库地址。这样依赖下载速度会快很多。版本冲突一般发生在spring-boot-starter-parent和某个第三方依赖之间解决办法是把第三方依赖的版本去掉统一使用SpringBoot的依赖管理。问题3前端启动后页面白屏打开浏览器控制台F12看报错。常见原因Vue CLI版本和Node版本不兼容、Element UI未正确引入、路由配置错误。这里有个经验Node版本不要装最新的LTS版本最稳。我当时用的Node 16.xVue CLI 4.x跑起来没有任何问题。6.2 业务代码问题问题1分页查询失效MyBatis-Plus的分页需要配置PaginationInnerInterceptor不然设置了pageSize和current也没用它会一次把所有数据查出来。这个拦截器必须在MybatisPlusInterceptor中注册Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; }问题2身份证号在前端显示为科学计数法Vue里用el-table显示身份证号时如果字段类型是number会变成科学计数法。解决办法是后端返回字符串或者前端用:formatter强制转字符串。更彻底的方案是身份证号在数据库里就用varchar存储这也是常规做法。问题3员工删除之后关联表数据不一致如果员工被删除他的考勤记录、请假记录、工资记录怎么办我的方案是员工采用逻辑删除deleted1关联查询时自动过滤被删除员工。如果做物理删除则必须设置外键级联删除否则会报外键约束错误。这里推荐逻辑删除虽然查询时多个条件但是数据一致性有保障。6.3 答辩高频提问及应对思路我把老师最可能问的问题整理成了一个速查表准备答辩前可以对着这张表自查一遍提问方向典型问题应对思路技术选型为什么选SpringBoot而不是SSH配置简化、内嵌容器、生态丰富、社区活跃、对比SSM的XML配置繁琐安全认证JWT和Session有什么区别token过期了怎么办JWT无状态、适合前后端分离过期让前端跳转登录页后端拦截器校验expiration数据库表的索引怎么设计的按查询场景建索引如employee表的手机号、考勤表的员工ID日期唯一索引权限控制怎么防止普通员工访问管理员接口拦截器校验角色管理员接口在权限判断里加role admin性能优化如果员工数据量大100万条怎么优化分页查询、索引优化、必要时引入缓存Redis但说明当前数据量下MySQL足够部署上线项目怎么部署的前端打包后由Nginx托管后端jar包用java -jar运行MySQL单独部署答辩的时候最忌讳的就是拿着代码念。老师更希望听到你用自然语言把整个系统的架构和业务流程讲清楚比如“用户从前端登录页输入账号密码后端接收到请求后先校验验证码再用JWT生成token返回给前端前端把token存起来后续所有请求都带上这个token后端通过自定义拦截器校验token的有效性。”这样讲虽然语言朴素但是能看出来你是真的理解整个流程。写在最后做毕业设计这一年我最大的体会是代码本身不是最难的最难的是“想清楚再动手”。这个人事管理系统看似简单但当你真的开始设计数据库时会发现每个字段的选择、每张表之间的关系都会影响后面的开发效率。技术栈用大众化的SpringBoot Vue MySQL反而是一种优势因为这让你能得到最多人的经验支持几乎所有你遇到的问题都能搜到答案。最后再分享一个小技巧项目做完了之后把完整的README.md写出来内容包括项目介绍、技术栈、功能列表、启动步骤、默认账号密码、项目结构说明。这不仅方便你自己在答辩前快速找回状态也是很多评委老师会关注的一个加分项。我当年就是因为README写得清晰老师直接在答辩现场照着README跑起来了项目整个过程非常顺利。本文还有配套的精品资源点击获取