ARTICLE DETAIL

资讯详情

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

Spring Boot + Vue 请假管理系统:从建表到审批状态机的完整实战

Spring Boot + Vue 请假管理系统:从建表到审批状态机的完整实战 简介这是一套面向软件开发学习者、毕业设计者以及需要快速搭建管理系统的初级开发者的请假管理系统完整项目资料。资源围绕员工请假申请、审批流转、记录查询与统计等核心业务整合了系统源码、高保真原型和数据库脚本适合用于课程设计、毕业设计或企业内训参考。压缩包共包含四个文件两个压缩包分别对应可运行的源码工程与交互原型一个数据库脚本内含完整表结构、初始化数据与查询视图另附一份PDF说明文档对系统架构、模块划分和部署步骤做了梳理整体仅14.28MB结构紧凑便于下载和本地运行。目前已有1036人学习使用资料覆盖从业务流程梳理、数据库设计到前后端代码实现的关键环节。读者可对照原型理解页面交互逻辑借助源码快速上手二次开发也能根据说明文档完成环境搭建与功能验证显著减少从零搭建成本原型页面覆盖申请、审批、个人记录等视图有助于快速把握系统全貌。1. 请假管理系统为什么说它是初学者的完整闭环项目很多人第一眼看到“请假管理系统”觉得这就是个CRUD教学题无非是把请假单存进数据库再让领导点头或摇头。但真在当前技术栈里把它从头做一遍你会发现它恰好卡在所有管理系统最共性、也最容易翻车的地方流程有状态流转、时间有重复与冲突、权限有角色差异、数据有日历与统计。它不是“项目里没有难点”而是难点都藏在业务规则的边界里——比如同一天能不能请两次假、跨天请假怎么算时长、撤回重提之后审批链怎么走。这套源码、原型与数据库的设计最典型的落地形态是给Java或Python课程设计、企业内部OA的简化版本做蓝本。它适合三类人第一次做完整前后端项目的学生、想快速搭出管理后台骨架的开发者、以及需要给团队演示“请假流程怎么跑通”的产品或测试人员。核心价值在于它让你在一周内看到一个管理系统的完整形状数据表怎么设计、接口和页面怎么串、审批状态机怎么转而不是只停留在某个框架的Hello World。下面按我实际做这类系统的顺序从选型、建表、接口、避坑一路说到发布直接给你能抄的作业。2. 先定技术选型单机部署的场景别让架构拖累实现2.1 前后端分离还是服务端渲染怎么选才不后悔我见过不少请假系统项目开发到一半因为技术选型太重而烂尾。最常见的错误是学校课程设计非要用微服务企业内部小工具非要用前后端分离加独立鉴权服务。对一个请假系统来说核心诉求是“表单填得顺、审批点得快、统计出得来”数据量撑死几千条。所以选型的第一原则是“你能独立跑通的最小闭环”。这里列一个我自己常用、也是多数源码包采用的技术组合层级技术选型选型理由前端Vue 3 Element Plus表格、表单、日期选择器开箱即用审批列表和请假表单都能直接套组件后端Spring Boot 3 MyBatis-Plus提供现成的CRUD和分页插件请假单的状态流转自己写也不复杂如果是Python方向用FastAPI SQLAlchemy同样成立数据库MySQL 8.0InnoDB事务支持好请假单提交和审批记录写入需要原子性原型辅助Axure 或即时设计画好页面原型再写代码能避免开发中反复改UI结构这个组合的边界是不要用它去扛多租户SaaS、不要做分布式审批、不要在单机里硬塞Redis缓存。请假系统的瓶颈从来不在性能而在业务规则的完整性——谁在什么状态下能做什么操作才是设计的重心。2.2 请假单为什么不能只有一张表五张表的结构与理由很多初学者建表第一反应是一张“请假表”加一张“用户表”字段堆上type、days、status就结束了。跑通时没感觉一遇到“我要查某个员工这个月请了几天假”“历史审批人是谁”就抓瞎。我一般会把表拆成五张分布如下employee员工表存工号、姓名、部门、职级、直属领导ID。注意要把“审批人”关系落在这张表上而不是写死在请假单里。leave_type请假类型表存年假、事假、病假、调休以及每种类型的每日上限比如病假超过3天需附证明。leave_request请假单主表存员工ID、类型ID、开始时间、结束时间、时长小时、原因、状态、当前审批节点。approval_record审批记录表存每一次审批动作——谁批的、批了什么、意见、时间。这张表是事后回溯的唯一凭证。leave_calendar工作日历表可选存节假日和调休安排用于跨天请假时准确计算工作日。这里最容易忽略的是approval_record。请假单的状态会被反复修改如果只留一个status字段历史就丢了。等你想回答“上个版本是谁否掉的、为什么否掉”的时候没有流水账就只能干瞪眼。一个请假单从提交到归档至少要经历3到5次状态变更每次都该留下痕迹。2.3 建表脚本与核心字段说明可以直接照抄的SQL下面给出核心表结构MySQL 8.0下直接执行。先建员工表再建请假单表因为外键依赖需要保证顺序。-- 员工表注意 leader_id 自关联指向本表中的直属领导 CREATE TABLE employee ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 员工ID, emp_no VARCHAR(32) NOT NULL UNIQUE COMMENT 工号, name VARCHAR(50) NOT NULL COMMENT 姓名, department VARCHAR(100) DEFAULT COMMENT 部门, position VARCHAR(50) DEFAULT COMMENT 职级, leader_id BIGINT DEFAULT NULL COMMENT 直属领导ID自关联, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, KEY idx_leader (leader_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT员工表; -- 请假单主表状态字段用TINYINT1待审批 2通过 3驳回 4已撤回 5已销假 CREATE TABLE leave_request ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 请假单ID, employee_id BIGINT NOT NULL COMMENT 申请人ID, leave_type_id BIGINT NOT NULL COMMENT 请假类型ID, start_time DATETIME NOT NULL COMMENT 请假开始时间, end_time DATETIME NOT NULL COMMENT 请假结束时间, hours DECIMAL(5,1) NOT NULL COMMENT 请假总时长小时, reason VARCHAR(500) DEFAULT COMMENT 请假原因, status TINYINT NOT NULL DEFAULT 1 COMMENT 状态1待审批 2通过 3驳回 4已撤回 5已销假, current_approver_id BIGINT DEFAULT NULL COMMENT 当前审批人ID, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY idx_employee (employee_id), KEY idx_status (status), KEY idx_start_time (start_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT请假单表; -- 审批记录表请自行补充核心字段leave_request_id, approver_id, action, comment, create_time参数说明hours用DECIMAL(5,1)而不是INT因为半天请假是4小时跨天可能带小数status用TINYINT注释便于在代码中定义枚举一一映射避免字符串状态在代码里到处飘。current_approver_id是冗余字段但很实用——列表页需要“我待办的审批”时一条索引就能查出来不用去联审批表。数据类型上时间字段一律用DATETIME不要用TIMESTAMP。TIMESTAMP有时区转换行为在跨时区或服务器时间配置异常时会莫名差8小时。相比省那一点存储空间后者在排查“明明请假9点到10点怎么显示成了1点到2点”这种问题时会让人怀疑人生。3. 从原型到接口把请假状态机画清楚代码就是翻译3.1 原型里必须画出的两个核心视图提交页与审批列表画原型不是走过场。请假系统里原型要重点解决两个交互问题一是请假时长怎么算二是审批按钮在什么状态出现。很多项目代码写乱了根源就是原型没定义清楚。提交页原型上需要固定以下元素请假类型下拉选、开始时间、结束时间、时长自动计算只读、请假事由多行文本。审批列表原型上最关键的是状态列和操作列要一一对应待审批的显示“通过/驳回”已通过的显示“销假/查看”已驳回的显示“重新提交/查看”。不要出现状态是“已通过”操作栏里还挂着“审批”按钮的情况。3.2 状态机的定义与后端接口划分六条核心接口请假的状态不宜超过6个我常用的状态机是草稿 - 待审批 - 通过/驳回通过后可选销假驳回后可重新提交。对应后端接口如下接口路径方法作用权限/api/leave/submitPOST提交请假单登录员工/api/leave/approvePOST通过或驳回审批人/api/leave/withdrawPOST撤回待审批的单申请人/api/leave/revokePOST销假回岗确认申请人/api/leave/listGET分页查询自己的单据登录员工/api/leave/approval/listGET查询待我审批的单据审批人用户在操作跳过状态时后端必须返回明确错误不能静默。Spring Boot里可以用一个Transactional方法处理审批动作先查单据校验当前状态再更新状态最后插入审批记录。3.3 时间冲突校验同一个人的请假区间不能重叠这是请假系统里第一个隐藏比较深的规则。实现不复杂但遗漏会导致严重逻辑漏洞。核心SQL判定如下SELECT COUNT(*) FROM leave_request WHERE employee_id #{employeeId} AND status IN (1, 2) -- 待审批和已通过都算占用 AND start_time #{newEndTime} AND end_time #{newStartTime};这条SQL的逻辑是两条请假区间重叠当且仅当新的开始时间早于旧的结束时间且新的结束时间晚于旧的开始时间。查询结果大于0说明存在重叠拒绝提交。要注意状态必须包含“待审批”和“已通过”已驳回的不算。这里容易踩的坑是只查了“已通过”结果一个员工同时提交两张待审批的单审批人全通过了排班就乱了。参数上newStartTime和newEndTime用DATETIME类型传入MyBatis-Plus里直接封装成LocalDateTime即可注意不要在前端转成字符串再传回来——格式化和时区问题会在不知不觉中引入脏数据。4. 请假管理系统避坑指南四个最容易翻车的地方4.1 plus时间字段是Date而不是LocalDateTime导致页面显示格式不对现象提交请假单后列表页显示开始时间是2025-06-01 09:00:00.0多出一个.0。原因后端实体类里把startTime定义成了java.util.DateJSON序列化默认输出带毫秒。前端拿到后直接渲染没做格式化。解决实体用LocalDateTime配合Jackson的jsr310模块配置spring.jackson.date-format无效但可以在application.yml里加spring.jackson.serialization.write-dates-as-timestamps: false前端收到的就是ISO字符串。前端再统一用dayjs做格式化显示。4.2 审批记录和请假单状态在异常时不一致现象审批人点“通过”页面上显示通过了但审批记录表里没有这条记录。原因更新请假单状态和插入审批记录是两条SQL没有放进同一个事务。第二条插入失败时第一条已经提交了。解决把审批动作抽成一个Transactional方法先插入审批记录再更新请假单状态。顺序不能反——因为审批人要看到“已审批”的状态但记录一旦没写进去后面就没法追溯了。用MyBatis-Plus时注意updateById默认只更新非空字段状态更新要显式调用。4.3 撤回审批中的单据没有校验操作人现象A提交给经理B审批结果另一个员工C调接口把这个单撤回了页面还没报错。原因withdraw接口只校验了单子存在且状态是“待审批”没有校验当前登录人是不是申请人本尊。解决在Service层取当前登录用户ID和leaveRequest.getEmployeeId()比对不一致直接抛权限异常。注意这个校验不能只在前端隐藏按钮——接口层面必须再拦一道因为隐藏按钮只防普通用户防不住直接调API的请求。4.4 销假功能缺失导致年假统计永远不对现象员工请了3天年假提前1天回来上班但系统里这3天都算消耗了月底统计年假余额对不上。原因没设计“销假”状态。请假单一进入“已通过”就固定了时长后续回岗早退没有走变更流程。解决增加销假动作员工回岗后对“已通过”状态的单据允许发起销假更新实际结束时间和实际时长并把单子置为“已销假”。统计时只看“已销假”和“已通过”但不跨月的部分避免重复计算。5. 我认为最好用的一套日常做法也是我一直在用的套路每次接新的管理类小项目我都会先把状态流转画成一张A4纸贴到桌面当开发清单提交、撤回、审批、驳回、销假每个动作各自从哪个状态到哪个状态操作人是谁。然后按状态机的维度去写后端接口而不是按页面维度写。页面是视觉上的分组状态机是逻辑上的分组——按页面写代码会写出上帝类按状态机写代码每个方法都是小块出问题翻代码也快。这个项目的日常做法还可以落到一个地方打印功能。请假单批完要纸质版存档这是国内企业OA的真实需求。我一般用浏览器的window.print()配合CSS的media print规则把审批通过后的详情页做成打印专用样式隐藏导航栏、按钮、表格操作列只保留单据主体、审批链时间线和二维码。好处是不引入额外依赖打印出来效果也接近纸质单。代码里这套方案落到approve接口时最后一步是生成审批链文本。如果你也在做类似的系统建议不要直接复制网上的通用权限代码而是先把employee表里的leader_id和role设计明白——审批流只要单层领导审批系统复杂度会降低一半。我踩过最大的坑就是把多级审批做复杂了结果一个请假单要过三个节点调试状态流转的时间比写整个系统还长。希望这篇梳理能帮你在做请假管理系统时少走几步弯路。本文还有配套的精品资源点击获取
返回列表