SpringBoot+Vue3 企业考勤如何处理法定假期?节假日方案、调休补班与工作日判断链路拆解

SpringBoot+Vue3 企业考勤如何处理法定假期?节假日方案、调休补班与工作日判断链路拆解

🌐 文档地址http://ruoyioffice.com | 📦 源码1https://gitcode.com/zhouzhongyan/ruoyi-office-vben.git | 📦 源码2https://gitcode.com/zhouzhongyan/ruoyi-office.git
考勤系统最容易被低估的地方,不是"能不能打卡",而是"今天到底要不要打卡"。春节放假、五一调休、国庆补班、企业自定义假期、部门差异化考勤规则,这些都不能靠简单的 周一到周五 解决。RuoYi Office 的 HRM 考勤模块用 节假日方案主表 + 明细表 + 考勤配置关联 + 工作日判断链路,把法定假期、调休补班和打卡记录生成串成了一条可配置、可追溯、可扩展的业务链路。

▲ 法定假期工作日判断链路:先按部门获取考勤配置,再读取关联的节假日方案,节假日明细优先于周规则,最终决定是否生成工作日打卡与前端打卡按钮状态

引言:为什么考勤不能只判断周末?

如果一个考勤系统只写了下面这段逻辑:

java 复制代码
boolean isWorkDay = dayOfWeek >= 1 && dayOfWeek <= 5;

它很快就会在真实企业里失效。

春节假期可能覆盖工作日:周一到周五并不一定要上班,系统如果继续生成缺卡记录,HR 后续需要批量修正。

调休补班可能落在周末:周六、周日也可能是工作日。如果系统默认周末不生成记录,员工打卡会变成"加班"或"非工作日打卡",统计结果就错了。

不同企业、不同地区安排不同:全国法定假日是一套基础规则,但部分企业会有年会假、厂休、地方性假期、项目制补班。

考勤配置还存在部门继承:总部、分公司、项目部可能继承上级考勤规则,也可能单独挂一套节假日方案。

所以,企业考勤里的"今天是否工作日",不是一个日期工具函数,而是一条业务判断链路:

判断层级 作用 典型场景
部门考勤配置 决定该员工适用哪套规则 研发部门 9:00-18:00,工厂车间单独配置
节假日方案 覆盖特殊日期 春节休假、国庆补班、企业年会假
周工作日规则 兜底判断常规工作日 默认周一到周五
打卡记录链路 把判断结果落到员工每日数据 工作日预生成、非工作日提示加班

本文结合 RuoYi Office 的真实代码实现,拆解一个企业级考勤系统如何处理法定假期。


一、业务场景:法定假期背后的四类考勤问题

1.1 工作日被法定假期覆盖

元旦、春节、清明、劳动节、端午、中秋、国庆,大多数都可能落在周一到周五。对于考勤系统来说,这些日期虽然满足 workDays=1,2,3,4,5,但实际应该被识别为休假。

如果没有节假日明细覆盖,会出现三个问题:

问题 业务后果
系统生成空白打卡记录 全员显示缺卡或未打卡
员工打开打卡页仍显示"上班打卡" 用户体验混乱
后续薪资考勤统计误算 HR 需要人工修正异常

1.2 周末被调休补班覆盖

中国企业考勤最典型的复杂度是调休补班。比如春节前后的某个周日,虽然星期规则是休息日,但国务院放假安排要求补班。

这类日期不能被当作"非工作日"。正确逻辑应该是:

日期类型 星期规则 节假日明细 最终判断
普通周六 不在 workDays 无明细 非工作日
春节周三 workDays type=1 休假 非工作日
调休周日 不在 workDays type=2 补班 工作日

这就是为什么节假日明细必须优先于周规则。

1.3 企业自定义假期

真实企业不会完全照搬国家节假日:

  • 制造业可能有厂休日;
  • 学校、培训机构可能有寒暑假安排;
  • 分公司可能按所在地放地方性节日;
  • 项目团队可能为了上线设置临时补班。

RuoYi Office 没有把节假日写死在代码里,而是设计成"方案 + 明细"的可配置模型。HR 可以维护"2026 年国家法定节假日""山东省 2026 假期安排""集团总部假期安排"等不同方案,再让考勤配置关联其中一套。

1.4 多部门考勤配置与继承

考勤配置不是全局唯一的。RuoYi Office 的考勤配置按部门设置,并支持向上继承:

部门 是否独立配置 实际规则来源
集团总部 本部门配置
研发中心 继承集团总部
项目交付部 使用自己的考勤时间和节假日方案

这意味着"今天是否工作日"不能只看登录用户,还要先拿到用户部门,再拿到该部门最终生效的考勤配置。


二、系统设计:从配置到打卡的完整链路

2.1 模块组成

RuoYi Office 的节假日能力不是一个孤立页面,而是嵌入 HRM 考勤模块:

模块 前端位置 后端实现 职责
考勤配置 views/hrm/attendance/config/index.vue AttendanceConfigServiceImpl 按部门维护上下班时间、工作日、打卡模式、节假日方案
节假日方案 modules/holiday-plan-modal.vue HolidayPlanServiceImpl 维护年度节假日、休假/补班明细
考勤打卡 views/hrm/attendance/punch/index.vue AttendancePunchControllerPunchRecordServiceImpl 员工查看今日状态并执行打卡
打卡记录 views/hrm/attendance/punch-record/index.vue PunchRecordServiceImpl 管理员查看、导入、导出、编辑打卡记录
定时生成 XXL-Job PunchRecordGenerateJob 每日自动生成空白打卡记录

2.2 核心设计决策

设计点 RuoYi Office 的方案 为什么这样设计
节假日建模 主表 hrm_holiday_plan + 明细表 hrm_holiday_plan_detail 方案和日期拆开,便于按年度、地区、企业自定义
日期类型 type=1 休假,type=2 补班 一个字段表达"覆盖为非工作日"或"覆盖为工作日"
考勤关联 hrm_attendance_config.holiday_plan_id 部门考勤规则可以绑定不同方案
更新明细 先删后插 节假日明细量小,全量替换更简单可靠
判断优先级 节假日明细优先,周规则兜底 支持工作日放假、周末补班两类覆盖
前端体验 配置页内弹窗维护方案 HR 配置考勤时就能顺手维护节假日

2.3 判断链路全景

一条完整链路可以拆成 6 步:

  1. 员工打开考勤打卡页;
  2. 后端根据登录用户获取部门;
  3. AttendanceConfigServiceImpl 查询本部门配置,没有则递归查父部门;
  4. 配置中如果有 holidayPlanId,调用 HolidayPlanServiceImpl.getHolidayType(planId, today)
  5. 如果当天存在节假日明细,type=1 返回非工作日,type=2 返回工作日;
  6. 如果没有明细,再根据 workDays 判断今天星期几是否在工作日列表中。

这一层顺序非常关键:节假日明细是人工配置的强规则,周规则只是默认规则


三、流程设计:HR 配方案,员工少困惑,系统少修正

3.1 HR 配置流程

HR 侧的操作路径是:

  1. 进入 人力资源管理 → 假勤管理 → 考勤配置
  2. 在左侧部门树选择部门;
  3. 在右侧配置打卡模式、工作日、上下班时间;
  4. 在"应用节假日方案"下拉框选择年度方案;
  5. 如果没有合适方案,点击"配置"打开节假日方案弹窗;
  6. 新增年度方案,逐条录入休假/补班日期;
  7. 保存考勤配置,让部门规则生效。

▲ 考勤配置页面:考勤规则与节假日方案在同一页面完成关联,HR 不需要在多个菜单之间来回切换

3.2 员工打卡流程

员工侧只感知结果,不需要理解复杂规则:

场景 打卡页表现
普通工作日 显示"上班打卡 / 下班打卡"
法定休假日 显示非工作日逻辑,打卡会提示加班
调休补班日 按工作日处理,正常显示打卡
无考勤配置 提示暂无配置
已完成签到签退 显示打卡完成

前端 punch/index.vue 使用 isWorkDay 控制按钮文案:如果后端返回非工作日,按钮会显示"加班签到 / 加班签退",并在打卡前弹窗确认"当前为非工作日,本次打卡将记为加班"。

3.3 后台打卡记录流程

管理员可以在 punch-record 页面查看全量打卡记录,支持:

能力 价值
部门树筛选 HR 快速查看某部门考勤
新增/编辑记录 处理异常补录
批量删除 清理错误导入或测试数据
导入/导出 对接线下考勤机或薪资核算

当节假日判断准确后,打卡记录页面里需要人工修正的异常会明显减少。


四、功能实现:Vue3 配置页如何承载节假日方案

4.1 考勤配置里的 holidayPlanId

前端 API 类型中,考勤配置直接包含 holidayPlanId

typescript 复制代码
export namespace AttendanceConfigApi {
  export interface AttendanceConfig {
    id?: number;
    deptId?: number;
    deptName?: string;
    /** 工作日(1=周一...7=周日,逗号分隔) */
    workDays?: string;
    /** 关联节假日方案ID */
    holidayPlanId?: number;
    workStartTime?: string;
    workEndTime?: string;
    /** 是否继承自父级 */
    inherited?: boolean;
  }

  export interface HolidayPlanDetail {
    holidayDate?: string;
    /** 类型(1=休假 2=补班) */
    type?: number;
    name?: string;
  }
}

这个字段让考勤配置和节假日方案形成松耦合:方案可以复用,部门可以选择,后端判断时只需要拿到最终配置。

4.2 节假日方案弹窗

holiday-plan-modal.vue 采用"列表视图 + 表单视图"的设计:

视图 功能
列表视图 展示已有方案,支持新增、编辑、删除
表单视图 编辑方案名称、年度、状态、备注和明细
明细行 选择日期、输入名称、选择休假/补班
统计信息 实时显示休假天数、补班天数、明细总数

添加明细时,前端会做两件小但重要的事:

  1. 同一日期不能重复添加;
  2. 明细按日期排序,方便 HR 检查全年安排。

4.3 考勤打卡页消费 isWorkDay

打卡页不再自己判断节假日,而是消费后端返回的 isWorkDay

typescript 复制代码
const isWorkDay = computed(() => punchInfo.value.isWorkDay !== false);
const punchBtnText = computed(() => {
  if (!punchInfo.value.hasConfig) return '暂无配置';
  if (isAllDone.value) return '打卡完成';
  if (!isWorkDay.value) {
    return nextPunchType.value === 1 ? '加班签到' : '加班签退';
  }
  return nextPunchType.value === 1 ? '上班打卡' : '下班打卡';
});

function handlePunch() {
  const punchType = nextPunchType.value;
  const statusFlag = getStatusFlag();
  if (!isWorkDay.value) {
    Modal.confirm({
      title: '非工作日打卡',
      content: '当前为非工作日,本次打卡将记为加班,确认继续吗?',
      onOk: () => executePunch(punchType, 0, true),
    });
    return;
  }
  executePunch(punchType, statusFlag);
}

这种设计把复杂判断留在后端,前端只负责交互呈现,避免 PC、APP、小程序各端重复实现一套节假日规则。


五、后端核心实现:主从表保存与工作日判断

5.1 保存节假日方案:主表 + 明细

节假日方案保存位于 HolidayPlanServiceImpl.saveHolidayPlan。核心策略是:新增时插入主表;更新时先校验主表存在,再更新主表,并删除旧明细;最后把请求中的明细逐条插入。

java 复制代码
@Override
@Transactional(rollbackFor = Exception.class)
public Long saveHolidayPlan(HolidayPlanSaveReqVO saveReqVO) {
    HolidayPlanDO plan = BeanUtils.toBean(saveReqVO, HolidayPlanDO.class);

    if (saveReqVO.getId() != null) {
        validateExists(saveReqVO.getId());
        holidayPlanMapper.updateById(plan);
        // 更新时全量替换明细,避免前端增删改差异计算复杂化
        holidayPlanDetailMapper.deleteByPlanId(saveReqVO.getId());
    } else {
        if (plan.getStatus() == null) {
            plan.setStatus(1);
        }
        holidayPlanMapper.insert(plan);
    }

    if (saveReqVO.getDetails() != null) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        for (HolidayPlanDetailSaveReqVO detailVO : saveReqVO.getDetails()) {
            HolidayPlanDetailDO detail = new HolidayPlanDetailDO();
            detail.setPlanId(plan.getId());
            detail.setHolidayDate(LocalDate.parse(detailVO.getHolidayDate(), fmt));
            detail.setType(detailVO.getType());
            detail.setName(detailVO.getName());
            holidayPlanDetailMapper.insert(detail);
        }
    }
    return plan.getId();
}

这里的"先删后插"不是偷懒,而是符合业务特性的取舍:一年节假日明细通常几十条以内,维护时更关心最终配置是否准确,不需要为每一行做复杂差异合并。

5.2 查询日期类型:按方案和日期精确命中

工作日判断需要一个非常小的查询接口:给定方案 ID 和日期,返回当天是休假、补班,还是没有特殊配置。

java 复制代码
@Override
public Integer getHolidayType(Long planId, LocalDate date) {
    if (planId == null) {
        return null;
    }
    HolidayPlanDetailDO detail =
            holidayPlanDetailMapper.selectByPlanIdAndDate(planId, date);
    return detail != null ? detail.getType() : null;
}

default HolidayPlanDetailDO selectByPlanIdAndDate(Long planId, LocalDate date) {
    return selectOne(new LambdaQueryWrapperX<HolidayPlanDetailDO>()
            .eq(HolidayPlanDetailDO::getPlanId, planId)
            .eq(HolidayPlanDetailDO::getHolidayDate, date));
}

返回值含义很清晰:

返回值 含义 后续处理
1 休假 强制非工作日
2 补班 强制工作日
null 无特殊配置 回退到 workDays

5.3 工作日判断:节假日明细优先于周规则

真正的判断逻辑在 AttendancePunchController.isWorkDay。这段代码最重要的不是语法,而是优先级:

java 复制代码
private boolean isWorkDay(AttendanceConfigRespVO config) {
    LocalDate today = LocalDate.now();
    int dayOfWeek = today.getDayOfWeek().getValue(); // 1=周一 ... 7=周日

    // 1. 节假日方案优先:休假覆盖工作日,补班覆盖周末
    if (config.getHolidayPlanId() != null) {
        Integer holidayType =
                holidayPlanService.getHolidayType(config.getHolidayPlanId(), today);
        if (holidayType != null) {
            if (holidayType == 1) {
                return false;
            }
            if (holidayType == 2) {
                return true;
            }
        }
    }

    // 2. 没有节假日明细时,回退到每周工作日规则
    String workDays = config.getWorkDays();
    if (workDays == null || workDays.isEmpty()) {
        workDays = "1,2,3,4,5";
    }
    Set<Integer> workDaySet = Arrays.stream(workDays.split(","))
            .map(String::trim)
            .filter(s -> !s.isEmpty())
            .map(Integer::parseInt)
            .collect(Collectors.toSet());
    return workDaySet.contains(dayOfWeek);
}

这条链路解决了两个关键问题:

  • 春节周三:workDays 认为是工作日,但明细 type=1,最终非工作日;
  • 调休周日:workDays 认为是休息日,但明细 type=2,最终工作日。

5.4 生成打卡记录:从固定周末跳过到方案化判断

当前 PunchRecordGenerateJob 每天触发 PunchRecordServiceImpl.generateDailyPunchRecords(),为在职员工生成当天空白打卡记录。真实实现里已经具备"在职员工过滤、幂等跳过、空白记录生成"的基础链路:

java 复制代码
@XxlJob("punchRecordGenerateJob")
@TenantJob
public String execute() {
    log.info("[execute][开始自动生成每日打卡记录]");
    return punchRecordService.generateDailyPunchRecords();
}

public String generateDailyPunchRecords() {
    LocalDate today = LocalDate.now();
    List<EmployeeDO> employees = employeeMapper.selectList(
            new LambdaQueryWrapperX<EmployeeDO>()
                    .notIn(EmployeeDO::getEmployeeStatus,
                            EmployeeStatusEnum.RESIGNED.getStatus(),
                            EmployeeStatusEnum.RETIRED.getStatus())
    );

    for (EmployeeDO employee : employees) {
        if (punchRecordMapper.existsByUserIdAndRealDate(employee.getUserId(), today)) {
            continue;
        }
        PunchRecordDO record = new PunchRecordDO();
        record.setUserId(employee.getUserId());
        record.setUserName(employee.getName());
        record.setDeptId(employee.getDeptId());
        record.setDeptName(employee.getDeptName());
        record.setRealDate(today);
        fillDateFields(record);
        punchRecordMapper.insert(record);
    }
    return "生成完成";
}

结合节假日方案后,生成逻辑应该复用同一条工作日判断链路,而不是单独写"周六周日跳过"。伪代码如下:

java 复制代码
public String generateDailyPunchRecords() {
    LocalDate today = LocalDate.now();
    List<EmployeeDO> employees = getActiveEmployees();

    for (EmployeeDO employee : employees) {
        AttendanceConfigRespVO config =
                attendanceConfigService.getAttendanceConfigByDeptId(employee.getDeptId());
        if (config == null || !isWorkDay(config, today)) {
            continue; // 法定休假日跳过,调休补班日继续生成
        }
        if (punchRecordMapper.existsByUserIdAndRealDate(employee.getUserId(), today)) {
            continue; // 幂等保护
        }
        PunchRecordDO record = buildEmptyPunchRecord(employee, today);
        punchRecordMapper.insert(record);
    }
    return "生成完成";
}

注意这里的重点:调休补班要按工作日处理。如果仍然只按周末跳过,周日补班就不会预生成记录,后续打卡与统计都会出现口径不一致。


六、数据结构:两张节假日表 + 一个配置关联字段

6.1 hrm_holiday_plan:方案主表

字段 类型 含义
id bigint 主键
name varchar(100) 方案名称,如"2026年国家法定节假日"
year int 年度
status tinyint 状态,0=停用1=启用
remark varchar(500) 备注
creator/create_time/updater/update_time 通用字段 创建与更新信息
deleted bit 逻辑删除
tenant_id bigint 租户编号

建表示意:

sql 复制代码
CREATE TABLE `hrm_holiday_plan` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `name` varchar(100) NOT NULL COMMENT '方案名称',
  `year` int(11) NOT NULL COMMENT '年度',
  `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态(0停用 1启用)',
  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
  `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '租户编号',
  PRIMARY KEY (`id`) USING BTREE
) COMMENT='节假日方案';

6.2 hrm_holiday_plan_detail:方案明细表

字段 类型 含义
id bigint 主键
plan_id bigint 方案 ID
holiday_date date 日期
type tinyint 类型,1=休假2=补班
name varchar(100) 名称,如"元旦""春节""补班"
deleted bit 逻辑删除
tenant_id bigint 租户编号

建表示意:

sql 复制代码
CREATE TABLE `hrm_holiday_plan_detail` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `plan_id` bigint(20) NOT NULL COMMENT '方案ID',
  `holiday_date` date NOT NULL COMMENT '日期',
  `type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '类型(1=休假 2=补班)',
  `name` varchar(100) NOT NULL DEFAULT '' COMMENT '名称(如:元旦、春节、补班)',
  `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '租户编号',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_plan_id` (`plan_id`) USING BTREE,
  KEY `idx_holiday_date` (`holiday_date`) USING BTREE
) COMMENT='节假日方案明细';

明细表的关键字段就是用户要求的三件事:

字段 为什么重要
holiday_date 精确到某一天,作为工作日判断命中条件
type 决定覆盖方向,休假或补班
name 便于 HR 和员工理解,如"春节""劳动节补班"

6.3 hrm_attendance_config.holiday_plan_id

考勤配置表通过 holiday_plan_id 关联方案:

sql 复制代码
`work_days` varchar(50) NOT NULL DEFAULT '1,2,3,4,5'
  COMMENT '工作日(1=周一...7=周日,逗号分隔)',
`holiday_plan_id` bigint(20) DEFAULT NULL
  COMMENT '关联节假日方案ID',
`work_start_time` varchar(20) NOT NULL DEFAULT '09:00:00'
  COMMENT '上班打卡时间',
`work_end_time` varchar(20) NOT NULL DEFAULT '18:00:00'
  COMMENT '下班打卡时间',

这使得一个企业可以有多套节假日方案,而每个部门考勤配置只需要选择其中一套。


七、RuoyiOffice 创新设计:不是日历组件,而是考勤规则引擎的一部分

7.1 把节假日放进考勤配置,而不是系统字典

很多系统会把节假日做成一个全局字典,结果后续遇到分公司、地区假期、企业自定义假期时很难扩展。

RuoYi Office 将节假日方案作为考勤配置的一部分:

传统做法 RuoYi Office 做法
全局写死节假日 可维护多个年度方案
所有部门共用 部门配置可选择方案
只支持放假 同时支持休假与补班
代码里判断周末 配置明细优先于周规则

7.2 用 type 表达覆盖方向

节假日明细没有设计成复杂的状态机,而是用 type 表达最核心的业务语义:

  • type=1:这天不需要考勤,即使它是周一到周五;
  • type=2:这天需要考勤,即使它是周六或周日。

这个模型足够简单,也足够覆盖中国企业最常见的法定假期与调休补班。

7.3 与部门继承机制结合

AttendanceConfigServiceImpl 会先查本部门配置,没有则递归查父部门,并用 inherited 标记告诉前端当前规则来自上级。

这意味着节假日方案也天然继承:

场景 效果
新部门未配置考勤 自动继承上级节假日方案
分公司独立配置 可选择自己的假期方案
删除本部门配置 回到父级规则,减少维护成本

7.4 PC 打卡页只消费结果

前端不直接查询节假日明细,而是消费后端聚合后的 isWorkDay。这样做有三个好处:

  1. PC、移动端、小程序的口径一致;
  2. 节假日逻辑调整时只改后端;
  3. 前端交互更聚焦,不需要理解方案明细。

7.5 为薪资与考勤统计留下扩展点

节假日方案不仅服务打卡,还可以继续扩展到:

后续模块 可复用点
薪资核算 判断缺勤、加班、节假日工资
加班管理 非工作日打卡自动标记加班
请假管理 计算请假天数时排除休假日
排班管理 特殊班次与节假日规则叠加

这也是 RuoYi Office "OA · HRM · CRM · ERP,一站打通"的价值:一个基础规则不只服务单个页面,而是能沉淀为企业管理底座。


八、核心链路复盘:一个日期如何被判断为工作日?

我们用一个例子复盘:

假设今天是 2026-02-15,星期日,但它在节假日方案明细里被配置成"春节调休补班",type=2

步骤 输入 处理 输出
1 登录用户 获取用户部门 研发部门
2 部门 ID 查询考勤配置,必要时向父级继承 得到 holidayPlanId=1
3 方案 ID + 日期 查询 hrm_holiday_plan_detail 命中 type=2
4 type=2 节假日规则优先 返回工作日
5 打卡页 根据 isWorkDay=true 显示正常上班打卡
6 定时任务 按工作日生成记录 生成空白打卡记录

如果今天是春节假期里的周三,链路同样成立,只是 type=1 会把它覆盖成非工作日。


九、快速体验

可以按下面步骤体验 RuoYi Office 的法定假期考勤设计:

  1. 进入 人力资源管理 → 假勤管理 → 考勤配置
  2. 选择一个部门,查看是否继承上级配置;
  3. 点击"应用节假日方案"的配置入口;
  4. 新增"2026 年国家法定节假日"方案;
  5. 添加一条工作日休假明细,如 2026-05-01 / 休假 / 劳动节
  6. 添加一条周末补班明细,如 2026-05-09 / 补班 / 劳动节调休补班
  7. 保存方案,并在部门考勤配置中关联该方案;
  8. 打开考勤打卡页,观察 isWorkDay 对按钮文案和打卡提示的影响。
仓库 地址
前端 Vben https://gitcode.com/zhouzhongyan/ruoyi-office-vben.git
后端 GitCode https://gitcode.com/zhouzhongyan/ruoyi-office.git
后端 GitHub https://github.com/yuqing2026/ruoyi-office.git

结语

企业考勤里的法定假期处理,本质上不是"多维护一个日历",而是把"某一天是否需要考勤"从硬编码判断升级为可配置规则。

RuoYi Office 的设计重点在三点:节假日方案明细优先于周规则、考勤配置关联方案、打卡与记录生成复用同一套工作日口径。这样才能同时处理工作日放假、周末补班、部门差异化和后续薪资统计扩展。

一套代码,通吃多端;一套规则,贯穿配置、打卡、记录和统计,这就是企业级考勤系统应该具备的工程闭环。


💡 RuoYi Office ------ 一个平台,管好整个企业

🌐 在线演示http://ruoyioffice.com/web/(账号 admin / admin123)

💬 技术咨询 :添加 17156169080,备注「RuoYi Office」

如果觉得不错,请给个 Star 支持一下!

复制代码
相关推荐
xmjd msup2 小时前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
Vane12 小时前
从零开发一个AI插件,经历了什么?
人工智能·后端
952362 小时前
SpringBoot统一功能处理
java·spring boot·后端
rleS IONS2 小时前
SpringBoot中自定义Starter
java·spring boot·后端
DevilSeagull3 小时前
MySQL(2) 客户端工具和建库
开发语言·数据库·后端·mysql·服务
TeDi TIVE4 小时前
springboot和springframework版本依赖关系
java·spring boot·后端
雨辰AI4 小时前
SpringBoot3 + 人大金仓 V9 微服务监控实战|Prometheus+Grafana+SkyWalking 全链路监控
数据库·后端·微服务·grafana·prometheus·skywalking
二哈赛车手4 小时前
新人笔记---ES和kibana启动问题以及一些常用的linux的错误排查方法,以及ES,数据库泄密解决方案[超详细]
java·linux·数据库·spring boot·笔记·elasticsearch
Nicander4 小时前
理解 mybatis 源码:vibe-coding一个mini-mybatis
后端·mybatis