☰
SpringBoot+Vue+MySQL工资信息管理系统源码详解:从启动到二次开发
2026/10/1 17:40:37 网站建设 项目流程

但凡做过JavaWeb课程设计的人,应该都体会过那种崩溃感:代码从网上翻来了,业务逻辑也看懂了,结果第一步建库就卡住,好不容易建完库,后端启动又报红,前端更是装依赖装到怀疑人生。今天要聊的这套工资信息管理系统源码,属于少见的“真能直接跑”的类型——SpringBoot做后端接口,Vue做前端页面,MySQL存数据,三者分工明确,SQL脚本和配置文件都给你备好,拿到手主要改一个数据库密码就能看到完整页面。它不是那种只有登录注册的玩具Demo,而是把部门管理、员工档案、工资核算、统计查询这些业务串起来的小型前后端分离项目。适合三类人:正在找课程设计题目的学生、刚学完SpringBoot和Vue想做综合练习的开发者、以及公司内部临时需要一个工资台账原型的运维或产品同学。这篇文章我会从功能边界、技术选型、启动步骤、坑点排查、表结构设计、二次开发六个角度把它拆透。

1. 这套系统能做什么:先看清楚功能边界再动手

很多人拿到源码第一反应是直接点启动,结果跑起来了却发现功能和自己想的不一样,又来来回回改。我的习惯是先看三样东西:README、数据库SQL脚本、前端路由表,五分钟就能把系统全貌拼出来。别小看这一步,搞清楚“它到底有什么、没有什么”,比急着启动重要得多。

1.1 核心功能模块梳理

工资信息管理系统这个题目听起来简单,实际展开之后内容并不少。常规设计会包含四个角色型模块:

模块核心功能对应的菜单/页面
系统管理登录、修改密码、注销登录页、个人中心
基础数据部门维护、员工档案维护部门管理、员工管理
工资业务工资项目设定、月度工资核算、工资查询工资核算、工资列表
统计分析按部门汇总、按月度趋势、员工工资明细统计报表

员工管理一般是系统的地基。每个员工关联一个部门,带有岗位、入职时间、基础工资等字段。工资核算则是按月生成工资记录,把基础工资、津贴、加班费、缺勤扣款、社保代扣这些项目汇总成实发工资。最后统计报表把每个月的数据按部门和岗位做聚合,方便财务或者管理层查看。

从技术形态上说,这套系统的数据流非常清晰:管理员登录后维护部门,再把员工挂到部门下;每个月做工资核算,系统按员工基础工资和当月考勤参数算出一笔工资;所有工资记录沉淀到工资表中,供查询和统计。这个业务闭环小但是完整,做课程设计来说绰绰有余。

1.2 它适合谁,不适合谁

我倾向于用一句话概括它的定位:解决中小型单位工资管理的常规需求,而不是复杂薪酬体系。多级审批流、个税专项附加扣除、社保公积金自动重算、银行代发文件导出这类功能,它大概率没有,也不该指望一套课程设计源码自带这些能力。

如果你是自己做毕设或者期末课程设计,这套代码是很好的参照物。业务体量适中,三四张核心表,前后端接口能对应上,答辩时可以把“为什么这样建表”“为什么用前后端分离”讲清楚,老师不会为难你。如果你是企业内部需要快速搭一个原型验证流程,它也能胜任——不用从零写起,跑起来之后把字段和页面微调一下就能演示。但如果你打算拿它支撑几百人规模的正式薪资流程,我劝你冷静,这种体量的系统在权限审计、数据一致性和容错上还差着层级。

2. 技术栈为什么是这三件套:从结构看可运行性

SpringBoot + Vue + MySQL 在今天的JavaWeb生态里几乎成了“标准答案”,但很多学习者只知道这个组合流行,说不清它为什么能凑到一块。我讲讲三者各自承担的角色,以及为什么“可直接运行”这件事能成立。

2.1 三者各管一段,边界清晰

Vue负责的是用户能看到的一切:登录表单、员工表格、工资核算按钮、统计图表。它运行在浏览器里,通过HTTP请求向后端要数据,拿到之后渲染成页面。SpringBoot负责的是所有业务规则:登录校验、部门增删改、工资计算逻辑、报表聚合,它不关心页面长什么样,只把JSON格式的数据返回给前端。MySQL负责的是记忆:员工信息存在员工表,工资记录存在工资表,用户密码存在用户表,等需要的时候再查出来。

用一个餐厅来类比:Vue是大堂里的菜单和点餐平板,用户直接和它打交道;SpringBoot是后厨,收到点单需求之后按规则制作;MySQL是仓库,备料都在里面,后厨随时取用。前后端分离的含义就是,点餐平板和后厨之间只通过标准格式的订单(JSON)沟通,换菜单不动后厨,换后厨不动平板。

2.2 “可直接运行”的关键是什么

这类源码标题里最爱写“可直接运行”,但真正跑不跑得起来,取决于三件事。

第一,数据库脚本是否齐全。很多源码只有代码不带SQL,或者SQL文件里没有预设部门和员工数据,导致系统启动后一片空白,还得自己疯狂补数据。这套系统附带完整的建库建表脚本和演示数据,执行完就有可登录的账号、可查询的员工记录,演示起来不费劲。

第二,前后端联调是否通畅。前端开发服务器启动后,默认会监听一个端口,比如5173或8081。前端代码里的请求地址如果写死成后端地址,部署时换一台电脑就得改源码。这套系统用代理转发的方式,前端把请求发到自己端口下的/api路径,由开发服务器转发到后端的8080,运行环境变了一般不需要动前端代码。

第三,配置文件是否集中。数据库地址、端口、账号密码集中在application.yml里,前端代理配置集中在vite.config.js里。新环境只需要改一处,不用满项目翻常量替换。

2.3 为什么这个组合适合学习和快速交付

对比早年的JSP时代,前后端代码混在同一个工程里,改个按钮样式都要重新编译发布整个应用。现在前后端分离,后端只关注接口,前端只关注页面,任意一个都可以单独测试。对比微服务架构,SpringBoot + Vue + MySQL又足够简单——后端就是一个进程,不涉及服务注册、配置中心、消息队列,学习成本低很多。把这三件事想明白,你再去看源码里那些接口定义和页面调用,会顺畅得多。

3. 从下载到浏览器出页面:五步启动法

我在这个项目上实测过完整启动流程,按下面的步骤来,正常情况下十分钟以内能看到登录页。这里给出一份环境版本对照表,先按版本要求准备,能避开后面一大半问题。

3.1 环境准备:版本比最新更重要

组件推荐版本说明
JDK1.8 或 11对应SpringBoot 2.x,最稳妥
Maven3.6 以上用于后端依赖管理和启动
Node.js14 到 18前端依赖安装和开发服务器运行
npm/cnpm随Node自带建议配置国内镜像源
MySQL5.7 或 8.05.7最稳,8.0需注意SSL问题
数据库工具Navicat或命令行用于导入SQL脚本

这里要专门提醒一下:版本不要盲目追求最新。SpringBoot 3.x 要求JDK17,很多教程和源码还停留在JDK8语法;Node 20以上跑老项目里的node-sass依赖经常直接失败。用跟源码匹配的稳定版本,比用最新版本省心得多。

3.2 第一步:创建数据库并导入脚本

用Navicat或者命令行连接本地MySQL,先建一个库,再执行项目里附带的SQL文件。命令行方式如下:

mysql -uroot -p

登进去之后执行:

CREATE DATABASE salary_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE salary_system; SOURCE /path/to/salary_db.sql;

导入完成后,可以查看一下表:

SHOW TABLES;

正常情况下能看到sys_user、dept、employee、salary等核心表,并且sys_user表里已经有预设管理员账号。如果这里查不到表,就别往后走了,说明SQL脚本没导入成功,后面后端启动必然报“Table doesn't exist”。

3.3 第二步:修改数据库连接配置

打开后端项目的application.yml,找到spring.datasource这一段,改成你本机的账号密码:

spring: datasource: url: jdbc:mysql://localhost:3306/salary_system?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8 username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver

注意URL里的useSSL=false和serverTimezone=Asia/Shanghai,这两个参数能直接规避掉MySQL 8.0最常见的两个启动报错,后面排错章节我再细说。

3.4 第三步:启动后端服务

在项目根目录执行:

mvn spring-boot:run

也可以直接用IDEA打开后端工程,等Maven依赖下载完,运行主类里的main方法。启动成功的标志是控制台出现:

Tomcat started on port(s): 8080 (http)

看到这句才算真正起来了。如果提示端口被占用,去application.yml里把server.port改成8081,同时记得前端代理地址也要跟着改。

3.5 第四步:安装前端依赖并启动

前端项目单独打开,先安装依赖:

npm install

如果安装过程报错,先别急着重装,大概率是Node版本或者网络源的问题,可以切换成国内镜像再试:

npm config set registry https://registry.npmmirror.com npm install

安装成功后再启动开发服务器:

npm run dev

看到终端输出Local: http://localhost:5173之类的地址,用浏览器打开,就能看到登录页。用SQL脚本里预设的账号登录,比如admin/admin123,系统的主界面就出来了。

4. 先把坑踩平:启动过程中最容易翻车的地方

这一节我要把启动过程中最常踩的四个坑单独拿出来讲。原因很简单:这些坑我在这类项目上见得太多,而且报错信息都很有迷惑性,新手看了根本不知道问题出在哪。

4.1 MySQL 8.0的SSL连接错误与时区问题

这是所有坑里出现频率最高的一个。现象是后端启动后,控制台飘着一大段红色警告,核心句子大概是:

Establishing SSL connection without server's identity verification is not recommended

或者中文提示:The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized。

我第一次遇到时以为是什么严重故障,后来排查明白了:MySQL 8.0默认开启SSL要求,而JDBC驱动在没有明确指示时会对证书身份做校验,于是抛出警告甚至连接失败;同时服务器默认时区是东八区,驱动不认识,也会导致连接中止。解决办法就是把对应的参数写进连接URL,也就是我前面给的那段:

useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true

allowPublicKeyRetrieval=true是MySQL 8.0的另一个特殊要求。新版默认认证插件是caching_sha2_password,在没有SSL的首次连接中,客户端需要从服务器获取公钥来加密密码传输,这个参数不加,连接时会直接报公钥检索失败。

4.2 SpringBoot版本太高引发的依赖冲突

很多人习惯一上来就创建最新版SpringBoot工程,结果把老源码的依赖一整合就炸了。最常见的报错是:

package javax.servlet does not exist

原因一句话就能说清:SpringBoot 3.x基于Jakarta EE 9+,包名从javax.servlet改成了jakarta.servlet,老代码里全是javax.servlet,当然编译不过。另外SpringBoot 3.x强制要求JDK17,如果你本机是JDK8,启动时就会报UnsupportedClassVersionError。

解决办法不是硬着头皮改代码,而是把版本锁到SpringBoot 2.7.x,配合JDK8或11使用。2.7.x还是javax.servlet体系,和绝大多数课程设计源码完全兼容。顺便说一句,这类源码如果里面引入了minio、activemq之类的第三方组件,版本冲突会更明显,统一用一个稳定的SpringBoot基线版本是治本的办法。

4.3 Node版本太新导致前端依赖安装失败

前端启动失败的场景也很典型:执行npm install,装到一半,node-sass报错,或者直接提示python2 not found、gyp ERR之类。这不是你操作失误,是node-sass这类老依赖和Node版本高度绑定。Node 16时代还能编译,到了Node 18以上经常直接罢工。

最快的处理方式是切换到Node 16或者Node 14,或者用nvm管理多个Node版本随时切换。然后删除node_modules和package-lock.json再重新安装:

rm -rf node_modules package-lock.json npm install

如果项目用的不是node-sass而是新版Vite(vite 4/5),这类问题会少很多。但一旦你拿到的是Vite 2或者Vue CLI老工程,Node版本这个问题基本躲不开。

4.4 端口占用、跨域和前端路由404

后端8080端口被占用,启动时直接报端口冲突。Windows下用netstat -ano | findstr 8080查占用进程,用taskkill /PID 进程号 /F结束进程,或者干脆改后端端口。前端报跨域,多半是没走代理,直接请求了http://localhost:8080。正确的方法是让前端请求发到自己的开发服务器路径,比如/api/login,再由vite.config.js里的proxy转给后端。前端页面刷新后404,这是Vue Router的history模式问题——开发环境下由dev server自动处理,部署后需要Nginx配置try_files回退到index.html,这个放到后面部署章节说。

报错现象根因快速解决
SSL警告或时区报错MySQL 8.0驱动参数缺失URL加useSSL=false和serverTimezone
javax.servlet不存在SpringBoot 3与老代码不兼容改用SpringBoot 2.7.x + JDK8
node-sass安装失败Node版本太新切换到Node14/16后重装依赖
前端请求跨域未走代理或后端未开CORS配置vite proxy,统一用/api前缀

5. 走进代码:核心表结构和工资数据的流转过程

跑起来只是开始,如果你想通过这套系统学到东西,甚至答辩时讲得清楚,必须看懂数据是怎么表里流到页面上的。这里我把典型的表结构和接口逻辑梳理一遍,不一定和你拿到的源码一字不差,但这类课程设计项目的设计模式基本一致。

5.1 核心表设计与关键字段

表名作用关键字段
sys_user登录用户id, username, password, real_name, role
dept部门id, dept_name, leader, phone
employee员工档案id, emp_no, dept_id, name, position, base_salary, hire_date, status
salary工资记录id, emp_id, salary_month, base_salary, allowance, overtime, deduction, actual_salary, status
operate_log操作日志id, user_id, operate_type, operate_time, detail

这几张表之间的关联关系也很直观:user只管谁可以登录、是什么角色;employee通过dept_id关联到部门;salary通过emp_id关联到员工。工资记录里同时保存基础工资和计算后的实发工资,这样即使员工档案里的基础工资后来改过,历史月份的工资记录依然能查到当时的标准,这是工资系统里一个很重要的设计原则——工资是历史快照,不能跟着员工档案实时变动。

5.2 工资是怎么算出来的

工资核算页面的操作流程一般是:选择核算月份,系统查出所有在职员工,带出每个人的基础工资;页面配置当月津贴、加班费、缺勤扣款;提交后端,后端算出实发工资写入salary表;之后工资列表就可以按员工和月份查询了。

这里有个容易忽略的点:算出来的actual_salary,建议后端重新校验一遍,不要直接信任前端传过来的总额。例如实发工资应该等于基础工资加津贴加加班费减扣款,后端拿到明细后自己加一次,避免前端被篡改或者前端计算精度出错。这个习惯在生产系统里是基本要求,在课程设计代码里能做到就算加分项。

5.3 接口组织与权限设计

后端接口一般围绕资源命名,这个项目里大概是这样的风格:

POST /api/login 登录 GET /api/employee/list 员工分页列表 POST /api/employee/save 新增/修改员工 DELETE /api/employee/delete 删除员工 POST /api/salary/calculate 月度工资核算 GET /api/salary/list 工资查询 GET /api/report/dept 部门汇总统计

权限这块,课程设计项目通常用拦截器加Token的方式,登录后后端返回一个token,前端每次请求都带上。后端拦截器校验token,再根据用户角色决定能不能访问管理接口。前端则配合动态路由,管理员看到员工管理菜单,普通用户只能看到工资查询和统计。这个设计麻雀虽小五脏俱全,稍微扩展一下就能往Spring Security + JWT的完整方案上靠。

6. 别停在能跑:二次开发可做的几件事

把这套系统跑通、代码看明白之后,你会发现“能跑”和“好用”之间还隔着一大截。如果你打算把这份源码作为毕设基础,或者想通过它展示自己的工程能力,下面几个扩展方向是我比较推荐的。

6.1 最值得加的三个业务功能

第一,Excel批量导入导出。员工几十个可以手敲,几百个就不可能了。用EasyExcel或者Apache POI,在员工管理页加一个“批量导入”按钮,后端解析Excel批量插入;同时在工资查询页加“导出当月工资表”,财务尤其需要这个功能。

第二,工资条查看与下载。给普通员工增加一个“我的工资条”页面,登录后只能看到自己的工资明细,并且可以生成PDF或者网页版工资条。这个功能涉及行级数据权限,能在原有角色权限基础上再往深处走一步,面试时也有的讲。

第三,操作日志增强。基础代码里可能只记录了谁在什么时间做了操作,具体改了哪个员工、改前改后的值是什么,一般没有。把日志扩成“变更字段级”记录,才能算一个可信的审计系统。

6.2 代码层面的结构优化

如果只是加功能,而不重构结构,项目会越来越难维护。我建议优先做三件事。

统一返回值体。后端接口不要直接返回Map或者裸数据,定义一个Result<T>对象,包含code、message、data三个字段,前后端约定好状态码含义,联调效率会高很多。

实体、DTO、VO分层。数据库实体不要直接暴露给前端,尤其密码字段必须屏蔽;接口入参用DTO接收,返回给页面的数据组装成VO。三者的转换逻辑集中在各自的层里,避免后续改字段时到处寻找。

给写操作加事务。工资核算、批量导入这类操作涉及多表写入,必须加@Transactional。没有事务的情况下,一旦插入到一半报错,会出现工资表有记录但员工扣款状态没更新的脏数据,复盘时极其尴尬。

6.3 部署级别的一次升级

课程设计通常停留在本地运行,如果你想让它看起来更专业,可以做成标准的三层部署:前端执行npm run build产出静态文件,交给Nginx托管;后端mvn package打成jar包,用systemd或Docker容器运行;MySQL独立部署或者用Docker Compose统一编排。

Nginx配置里有一个关键点:前端路由用了history模式,必须加try_files $uri $uri/ /index.html;,否则用户刷新二级页面会404。同时/api路径需要反代到后端的8080端口,这样部署之后依然保持前后端分离的结构,切一刀就能从开发环境平滑过渡到生产环境。

如果你愿意,还可以把Docker Compose配置一起写出来,MySQL、后端、前端三个服务一条命令拉起来。能走到这一步,这份工资信息管理系统源码就不再是一个课程设计作业,而是一份可以写进简历的完整全栈项目经历。这也是我把这套源码推荐给身边朋友时最常说的一句话:先把它跑起来是及格,把它改到顺手才是优秀。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询