新闻详情

新闻详情

首页 / 资讯中心 / 详情

SpringBoot+Vue人事管理系统开发实战:从数据库设计到部署避坑全指南

发布时间:2026/10/1 17:33:40来源:尧图网络
SpringBoot+Vue人事管理系统开发实战:从数据库设计到部署避坑全指南
1. 项目整体架构与模块拆解为什么这套组合最适合毕设很多人一听“人事系统管理平台”就觉得太普通觉得满大街都是。但真到自己做毕设或者课程设计时才会发现“普通”恰恰是最大的优势。SpringBoot Vue MySQL 这套技术栈放在招聘市场和校园里都属于点名率最高的组合。人事系统本质上是一套“以员工数据为中心”的信息管理系统员工、部门、考勤、薪资、请假这些模块串起来以后你几乎能把 JavaWeb 里该练的东西全部过一遍CRUD、关联查询、权限控制、分页搜索、导入导出、定时任务甚至简单的审批流。这套源码适合谁如果你是毕业设计需要快速落地一个功能完整的系统或者作为课程设计想找一个能讲清楚、能演示、能扩写的项目又或者刚学完 SpringBoot 和 Vue 但不知道怎么把前后端黏在一起那它可以当一个很扎实的“样本工程”。学习价值远大于直接拿去商用因为人事系统里全是真实业务场景比网上各种“学生管理系统”的玩具项目有说服力得多。选择 SpringBoot Vue 最大的理由是“前后端分离足够清晰”。后端只做接口前端只负责展示和交互。你在答辩时可以分别讲清楚登录怎么鉴权菜单怎么根据角色生成员工查询怎么分页考勤数据怎么统计。这种拆解能力恰恰是评委最想听到的东西。1.1 人事系统到底要划哪些功能模块我建议不要一开始就想着做大而全的 HR 平台那会把自己拖死。一个既能体现工作量、又不至于做不完的人事系统可以把边界划在这六个模块上系统管理用户、角色、菜单权限、操作日志。这是整个系统的底座。组织管理部门列表和岗位信息通常做一张树形结构的部门表。员工管理员工花名册包括基本信息、入职时间、所属部门、状态、联系方式。考勤管理每日打卡时间、出勤状态、异常统计。请假与流程申请请假、按状态审批简单走一个“提交-审批-完成”的闭环。薪资管理按月生成工资表由基础工资、补贴、扣款等字段计算实发工资。这个划分逻辑是环环相扣的登录后先看到系统管理维护部门后才能录入员工员工有了考勤才谈得上工资。评委问你“为什么这样设计”你可以回答这是按主数据、业务数据、汇总数据三层来组织的部门员工是主数据考勤请假是日常业务数据薪资是汇总计算结果。这一句话就说明你不是只会写 CRUD。1.2 技术选型的时候想清楚这四件事第一后端基础框架用 SpringBoot 2.7.x 还是 3.x。如果你本地是 JDK 8老老实实用 SpringBoot 2.7.x否则 JDK 版本对不上启动就会报错。有些同学一开始就用最新版结果连javax.servlet和jakarta.servlet的差异都还没搞清楚白白浪费时间。第二ORM 用 MyBatis-Plus 而不是纯 MyBatis。人事系统里大量操作是单表增删改查和条件分页查询MyBatis-Plus 提供的QueryWrapper和IService能少写很多样板代码。纯 MyBatis 不是不行但课设和毕设的时间有限能省则省。第三数据库用 MySQL 5.7 或 8.0 都行。如果电脑上已经装了 8.0注意驱动要换成com.mysql.cj.jdbc.Driver并且连接串里加上时区参数。这个问题我在后面专门讲十个人里至少有两个人在这里卡住。第四前端框架用 Vue3 Vite Element Plus。Element Plus 的表格、表单、分页组件直接能撑起后台管理界面的大部分工作比手写 CSS 高效太多。Vue2 虽然还在不少老项目里躺着但新写的毕设没必要再选一个已经进入维护期的版本除非你对接的项目里明确要求 Vue2。2. 数据库设计是验收的第一道关卡很多同学做项目习惯先写代码后补表结构。我每次看到这种操作都想拦一下。人事系统的开发顺序应该是先梳理业务 - 再设计表 - 再写接口 - 最后做页面。数据库设计稿拿得出来评委就知道你真正把业务想清楚了。2.1 建议直接用的核心表结构以下是一套比较通用、可以直接拿去用的核心表清单我省略了每个字段的注释只列主干具体字段照着业务补即可表名核心字段作用sys_userid, username, password, real_name, role_id, status登录用户关联角色sys_roleid, role_name, role_key, status角色如管理员、HR、普通员工sys_menuid, parent_id, menu_name, path, component, icon, visible菜单和按钮权限deptid, parent_id, dept_name, sort, status组织部门树形结构employeeid, emp_no, name, gender, birth_date, dept_id, position, phone, id_card, entry_date, status, del_flag员工主数据attendance_recordid, emp_id, attendance_date, clock_in, clock_out, status每日考勤记录leave_requestid, emp_id, leave_type, start_time, end_time, reason, status, apply_time请假申请与审批状态salary_infoid, emp_id, month, base_salary, allowance, deduction, actual_salary, create_time月度薪资数据这里特别注意employee表里的emp_no和id_card要建唯一索引。人事系统里最怕同一个人录入两遍员工工号和身份证号是天然的防重字段。在 MySQL 建表时直接用UNIQUE KEY后端接口里再做一次兜底校验双重保险。2.2 设计表时最容易忽略的三个细节第一个细节是逻辑删除。员工误删了不能直接从库里消失否则历史考勤、工资都会对不上。所有业务表加一个del_flag字段默认 0删的时候改成 1。MyBatis-Plus 里用TableLogic标注一下查询时它会自动过滤已删除数据。听上去简单但很多人到答辩前才发现数据删了没法恢复只能从备份里捞。第二个细节是创建时间和更新时间。公共字段做成create_time、update_time插入时自动填充修改时自动更新。MySQL 8.0 可以直接用DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP也可以用 MyBatis-Plus 的自动填充在字段上标TableField(fill FieldFill.INSERT)。这个字段不是给用户看的是给你排查问题和展示系统规范性用的。第三个细节是状态字段用数字或字符串标记不要存中文。比如员工状态用0表示在职、1表示离职、2表示试用期请假状态用0待审批、1通过、2拒绝。以后要加筛选条件和国际化存数字都方便。如果直接存“在职”“离职”后面做统计报表的时候自己都想骂自己。3. 后端从零搭建从启动类到 JWT 登录后端这块是工作量的大头也是能体现技术水平的地方。你要是能把登录鉴权、统一响应、全局异常、分页查询、事务控制这几样写利索代码质量会比网上一大堆“只有 ControllerMapper”的项目高出一个段位。3.1 pom.xml 依赖与基础配置Maven 项目里核心依赖大致是这些dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-api/artifactId version0.11.5/version /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependencyJava 8 的话mysql-connector-java不需要写版本由 SpringBoot 2.7.x 的依赖管理统一控制。SpringBoot 3.x 则要换com.mysql:mysql-connector-j很多新手因为这一步没对齐直接启动失败。application.yml里最重要的两个配置是数据源和 MyBatis-Plus 的日志spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/hr_system?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: root password: 123456 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true这里useSSLfalse用于解决 MySQL 8.0 的 SSL 连接警告serverTimezoneAsia/Shanghai解决时区差八小时的问题。你把这个配置背下来能少踩一半的 MySQL 坑。3.2 登录认证与权限拦截登录接口看起来简单其实有三层逻辑要做。第一层根据用户名查用户密码用 BCrypt 校验。BCryptPasswordEncoder是 Spring Security 里的类即使你没有引入完整 Security也可以用这个加密工具。不要去学网上那些直接存明文密码的写法那在答辩时很减分。注册用户时密码加密存储登录时只比对密文。第二层生成 token。我建议用 JWT把用户 ID、用户名、角色编码放进去设置一个过期时间比如 24 小时。密钥放在application.yml里不要写到代码里这也是答辩时可说的工程规范。第三层写拦截器。SpringBoot 里实现HandlerInterceptor在preHandle中从请求头取出 token解析成功就把用户信息放进ThreadLocal或requestattribute解析失败直接返回 401。注意放行登录接口和 Swagger 文档相关路径其余接口全部拦住。配置拦截路径时直接用registry.addInterceptor().addPathPatterns(/**).excludePathPatterns(/login, /doc.html, /webjars/**)一套带走。这里想强调一个实战细节token 解析失败不能只返回一个字符串要和前端约定好统一格式。我习惯用{code:401,msg:登录已过期请重新登录}这样的 JSON 结构。前端 axios 拦截器拿到 401 后自动跳转登录页。这个闭环做通前后端联调的时候会非常舒服。3.3 统一响应体、分页查询和事务控制统一响应体就是定义一个泛型类ResultT里面固定有code、msg、data三个字段。成功返回code200失败返回code500或业务错误码。不要指望每个接口都返回MapString,Object那会让前端的类型判断变得一团糟。分页查询直接用 MyBatis-Plus 的Page。比如员工列表Controller 接收pageNum、pageSize、deptId、status、keyword参数Service 层里这样拼条件PageEmployee page new Page(pageNum, pageSize); LambdaQueryWrapperEmployee wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.hasText(keyword), Employee::getName, keyword) .eq(deptId ! null, Employee::getDeptId, deptId) .eq(status ! null, Employee::getStatus, status) .orderByDesc(Employee::getCreateTime); employeeMapper.selectPage(page, wrapper); return Result.success(page);这里有个细节值得展开like和eq前面那个布尔条件是“是否拼接这个条件”的开关。搜索关键词为空时不加模糊条件否则会把整表数据过滤成空这种写法比if判断清爽很多也是 MyBatis-Plus 的常规玩法。事务控制也很重要。考勤统计和薪资生成这类操作会同时影响多张表一旦中途失败数据就会对不上。在 Service 方法上加Transactional(rollbackFor Exception.class)把事务边界画清楚。曾经有个同学做薪资生成循环里跑前一天的数据时有个空指针没处理结果前半部分员工的工资已经写进去了后半部分失败最后对账对了两天才找到原因。加了一个事务注解就完事了这就是代码习惯问题。4. 前端 Vue 工程搭建与页面打通前端部分看着复杂其实只要把骨架捋顺剩下的就是照着 Element Plus 文档组装页面。很多人怕前端主要是被 Vue 的各种概念吓到了实际上你只需要抓住四条主线项目怎么起、路由怎么配、请求怎么发、表格怎么渲染。4.1 用 Vite 初始化前端项目并集成组件库创建项目直接执行npm create vitelatest hr-ui -- --template vue cd hr-ui npm install npm install vue-router4 pinia axios element-plus element-plus/icons-vue npm run dev这就是一个 Vue3 Vite 的最小骨架。如果你是第一次用可能会对node_modules那么大感到慌这是正常的。这个目录不用管是本地依赖。Element Plus 引入方式有全局引入和按需引入。做毕设为了省事我建议全局引入直接在main.js里import ElementPlus from element-plus import element-plus/dist/index.css app.use(ElementPlus)全局引入打包体积稍大但是代码量最小不用每个组件单独导入。项目做完了想优化再去折腾按需自动导入。4.2 axios 封装和动态菜单axios 封装是前端最值得认真写的一块。你要在src/utils/request.js里创建一个实例设好baseURL然后加请求拦截器和响应拦截器。请求拦截器统一从 localStorage 里拿 token塞进请求头响应拦截器处理业务错误和 401 跳转。菜单权限这边我这里有两个选择前端写死或后端动态返回。毕设为了提高完整度建议做动态菜单。登录成功之后请求后端接口获取当前用户能看到的菜单存进 Pinia然后路由用addRoute动态添加。这样不同角色登录后看到的侧边栏不一样很直观地展示了权限控制的效果。如果时间实在不够就退一步做成前端静态路由靠按钮v-if判断角色控制页面入口。例如管理员能看到用户管理HR 只能看到员工相关菜单。这个做法也能解释通但说服力不如动态路由。4.3 员工列表页如何做到开箱即用员工列表页是所有页面的模板你做通这一个页面后面考勤、请假、薪资都能照着抄。页面结构分三块上面是搜索栏中间是操作按钮下面是表格加分页。搜索栏里有部门选择框、在职状态选择框、姓名关键词输入框点“查询”后重新从后端拉数据。表格用el-table列里有姓名、工号、部门、职位、状态标签、入职日期、操作按钮。操作按钮里是编辑和删除。分页用el-pagination监听current-change和size-change事件把参数同步到查询条件里。这里的注意点是删除完最后一条数据后要判断当前页是否已经没有数据如果是就回退一页否则会一直停留在空页面上这是很多新手忽略的用户体验细节。表单弹窗就是el-dialog里套一个el-form新增和编辑复用一个组件通过form.id是否存在来判断提交时调的是新增接口还是修改接口。表单校验规则用 Element Plus 自带的rules比如必填字段、手机号格式、邮箱格式。提交成功后关闭弹窗刷新列表。5. 毕设提分技巧导入导出、定时调度和接口文档做完基础功能系统已经可以跑了但想拿高分还得加几个操作性强、答辩时一演示就亮眼的功能。这三个功能投入产出比最高Excel 导入导出、定时任务、接口文档。5.1 EasyExcel 让导出功能成为亮点人事系统里最常见的需求是把员工花名册导出成 Excel。网上很多老项目用 Apache POI 手动写Workbook代码长且容易乱。建议用阿里开源的 EasyExcel响应式写 Excel内存占用更小代码量少很多。引入依赖dependency groupIdcom.alibaba/groupId artifactIdeasyexcel/artifactId version3.3.2/version /dependency定义一个导出对象类字段上加ExcelProperty(员工工号)注解然后在 Controller 里一行一行写入响应流。前端点击“导出”直接打开后端导出接口路径浏览器就会下载文件。导入是反向操作从 Excel 里读数据到临时集合校验通过后逐条插入。这个功能面试时可以直接说数据量大时传统 POI 容易内存溢出EasyExcel 采用 SAX 逐行解析模式单次只加载一行数据所以无论是导入还是导出对内存占用都比较友好。5.2 定时任务把考勤统计做成自动化考勤模块如果只是一个打卡记录表那就太薄了。你可以加一个定时任务每天凌晨两点自动把昨天的打卡记录捞出来判断是否迟到、早退、缺卡然后更新状态字段。SpringBoot 里只需要两步启动类上加EnableScheduling然后在方法上写Scheduled(cron 0 0 2 * * ?)。这个 cron 表示每天凌晨两点执行一次。工资模块也可以用类似的逻辑每月 1 号自动生成上个月的工资记录按员工基础工资加上补贴减去扣款计算实发工资。这里有一个很重要的经验定时任务里一定要加日志记录本次跑了多少条数据、成功多少条、失败多少条最好再把执行结果写到一张任务日志表里。否则跑完了没有任何痕迹出问题都不知道是什么时候出的。5.3 用 Knife4j 给接口做个“说明书”后端接口一多前端对接和答辩演示都会乱。接入 Knife4j 后访问doc.html就能看到每个接口的请求方式、参数说明、返回结构不用再对着 Postman 一个个讲。依赖如下dependency groupIdcom.github.xiaoymin/groupId artifactIdknife4j-openapi2-spring-boot-starter/artifactId version4.4.0/version /dependency配合ApiModelProperty注解前端同学能直接看到每个字段的含义。答辩的时候打开这个页面评委如果问到某张表有哪些字段你直接在文档里指给他看专业感一下就出来了。6. 本地编译运行常踩的坑与排查办法这部分是从无数个“帮人远程调项目”的夜晚里攒出来的。很多问题不是代码逻辑不对而是环境不一致。下面这些坑发生率极高每一条都值得先存着。6.1 最容易让新手卡住的三个环境问题第一Tomcat 端口被占用。启动时报Port 8080 was already in use直接关掉占用端口的进程或者改后端的server.port和前端请求的端口一致。Windows 命令行用netstat -ano | findstr 8080看 PID再用taskkill /PID id /F强杀。第二MySQL 8.0 报 SSL 连接错误或Public Key Retrieval is not allowed。解决方法就是连接串加useSSLfalseallowPublicKeyRetrievaltrue。这个我在前面提过但还是要再说一次因为它真的能把人磨到没脾气。第三前端页面能打开但接口全部 404。多半是跨域或代理没配好。Vite 开发服务器在vite.config.js里配 proxy 就行server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true, rewrite: path path.replace(/^\/api/, ) } } }如果后端接口是/employee/list前端请求写成/api/employee/list代理会自动转发。这样前端代码里不必写完整的后端地址上线时也方便切换。6.2 部署和答辩前的检查清单答辩前两天我建议按下面这个清单过一遍避免现场翻车数据库备份一份起一个干净的测试库用初始化 SQL 能一键重建全部表结构和演示数据。管理员账号密码明文写在演示文档里比如 admin / 123456避免现场忘记。前端打包在项目根目录执行npm run build生成的dist目录放到 Nginx 里或直接用nginx -s reload刷新。如果前后端分离部署Nginx 里要把/api反向代理到 SpringBoot 服务注意前端刷新页面时路由要try_files回退到index.html否则一刷新就 404。准备两个演示场景一个是从登录到新增员工再到查询和导出另一个是异常场景比如没有权限访问某个菜单时会被拦截。评委喜欢看到你会处理异常。我把常见问题整理成一个速查表方便你直接对照问题现象大概率原因处理办法后端启动即失败端口占用、依赖版本冲突换端口或杀掉冲突进程统一依赖版本SQL 报错表不存在初始化脚本没执行或连错库检查数据库名和 application.yml页面接口 404跨域、代理未配、Controller 路径错误先看浏览器网络请求再查后端日志中文乱码连接串缺字符集参数URL 加 characterEncodingutf8登录成功但菜单空白角色没绑定菜单或前端动态路由失败验证角色菜单配置再查看接口返回导入 Excel 报错表头匹配不上、数据有非法格式用统一模板校验真实错误的前端提示这些坑基本都是“配置细节”引起的不是架构问题。花十分钟检查配置比你重写代码有用得多。我自己在这类项目上翻过车的地方是对“完成度”的判断太乐观。总以为把基本 CRUD 写完就万事大吉结果一演示导出功能就崩一换浏览器就跨域一刷新就 404。后来我把优化顺序改成先保证核心流程完整跑通再补导入导出和定时任务最后才去美化界面。这样即使时间不够交出去的东西也是能用的。如果你现在正拿着这套人事系统做毕设我建议你从数据库脚本开始跑不要着急看代码。先把表建起来再用初始化数据调通登录然后一个模块一个模块地打通页面。这个过程走完你会发现 SpringBoot 和 Vue 其实没有想象中那么难难的是你把它们拼成一个完整产品时的耐心。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Win7/8.1上Steam白屏与steamwebhelper崩溃的排查自救指南 2026/10/1 19:08:24

Win7/8.1上Steam白屏与steamwebhelper崩溃的排查自救指南

最近有个老伙计的Win7老机器上,Steam一打开就白屏,右下角反复弹“steamwebhelper没有响应”,点“重新启动”弹窗又冒出来,循环到人崩溃。他这台机器平时就是拿来开几个十年前的库存游戏,根本没打算换系统,结…

阅读更多 →
基于CNN的Landsat地物分类:h5模型与Python源码实践 2026/10/1 19:08:24

基于CNN的Landsat地物分类:h5模型与Python源码实践

简介:面向遥感与深度学习交叉应用,这套基于卷积神经网络的陆地卫星影像地物分类工程,针对传统分类方法依赖人工光谱特征、易受分类器性能限制的不足,借助深度网络自动提取影像的纹理、形状与上下文信息,实现水体、植被…

阅读更多 →
Win7打不开Steam?从TLS到运行库的完整排查与修复指南 2026/10/1 19:08:24

Win7打不开Steam?从TLS到运行库的完整排查与修复指南

先说明一个前提:Steam官方在2024年元旦之后,已经不再对Windows 7、Windows 8、Windows 8.1提供技术支持,但这并不等于Win7上的Steam立刻就不能用了。现实中还有不少老双核电脑、老爷机用户,习惯用Win7跑老游戏,或者某些…

阅读更多 →
Ubuntu下Anaconda可靠安装与深度适配指南 2026/10/1 19:08:24

Ubuntu下Anaconda可靠安装与深度适配指南

1. 为什么在 Ubuntu 上装 Anaconda 不是“点下一步”那么简单你搜“Ubuntu 安装 Anaconda”,首页跳出来的教程,十有八九是复制粘贴的三步走:下载 sh 文件 → chmod x → bash xxx.sh → 按回车 → 完事。我刚入行那会儿也这么干,直…

阅读更多 →
Iconify离线部署全攻略:解决图标不显示的四套可靠方案 2026/10/1 19:08:24

Iconify离线部署全攻略:解决图标不显示的四套可靠方案

“图标不显示”这件事,放在在线环境里通常五分钟就能定位,放到离线环境里就成了玄学。iconify 作为目前覆盖面最广的图标方案,很多人平时只用到它在线加载的那一面,却忽略了它本质上依赖一个远程 API;一旦项目要部署到…

阅读更多 →
OpenRig:面向本地多LLM推理的轻量级CLI调度工具 2026/10/1 19:08:17

OpenRig:面向本地多LLM推理的轻量级CLI调度工具

1. OpenRig 是什么?它不是 Codex,更不是 Node.js 的玩具项目 OpenRig 这个名字在当前技术社区里确实容易引发混淆——它既不是 Codex 的别名,也不是某个 Node.js 教程里的练习项目,更不是 Windows 上双击就能运行的桌面软件。我第…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉