-- 考勤设置独立保存与历史升级脚本 -- 执行日期:2026-03-23 -- 用途: -- 1. 将考勤设置改为单条独立保存、编辑、逻辑删除 -- 2. 为各配置表补充版本号、最后修改人、最后修改时间、逻辑删除字段 -- 3. 新增考勤配置历史表 -- 4. 为考勤打卡记录补充规则快照字段,保证后续可追溯当时命中的规则 -- 说明:脚本已兼容“表已存在 / 字段已存在 / 索引已存在”的场景,可重复执行 SET @db_name = DATABASE(); DROP PROCEDURE IF EXISTS sp_add_column_if_not_exists; DROP PROCEDURE IF EXISTS sp_add_index_if_not_exists; DELIMITER $$ CREATE PROCEDURE sp_add_column_if_not_exists( IN p_table VARCHAR(64), IN p_column VARCHAR(64), IN p_definition TEXT ) BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_table AND COLUMN_NAME = p_column ) THEN SET @ddl_sql = CONCAT('ALTER TABLE `', p_table, '` ADD COLUMN `', p_column, '` ', p_definition); PREPARE stmt FROM @ddl_sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END$$ CREATE PROCEDURE sp_add_index_if_not_exists( IN p_table VARCHAR(64), IN p_index VARCHAR(64), IN p_definition TEXT ) BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_table AND INDEX_NAME = p_index ) THEN SET @ddl_sql = CONCAT('ALTER TABLE `', p_table, '` ', p_definition); PREPARE stmt FROM @ddl_sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END$$ DELIMITER ; -- ======================================== -- 1. 新增考勤配置历史表 -- ======================================== CREATE TABLE IF NOT EXISTS `lq_attendance_config_history` ( `F_Id` varchar(50) NOT NULL COMMENT '主键ID', `F_ModuleType` int NOT NULL COMMENT '模块类型', `F_BizId` varchar(50) NOT NULL COMMENT '业务主键ID', `F_VersionNo` int NOT NULL DEFAULT 1 COMMENT '版本号', `F_OperateType` int NOT NULL COMMENT '操作类型(1新增,2修改,3删除)', `F_Title` varchar(200) DEFAULT NULL COMMENT '配置标题', `F_SnapshotJson` longtext COMMENT '配置快照JSON', `F_ChangeReason` varchar(500) DEFAULT NULL COMMENT '变更原因', `F_OperateUserId` varchar(50) DEFAULT NULL COMMENT '操作人ID', `F_OperateUserName` varchar(100) DEFAULT NULL COMMENT '操作人姓名', `F_OperateTime` datetime NOT NULL COMMENT '操作时间', PRIMARY KEY (`F_Id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考勤配置历史记录表'; CALL sp_add_index_if_not_exists( 'lq_attendance_config_history', 'idx_attendance_config_history_biz', 'ADD INDEX `idx_attendance_config_history_biz` (`F_ModuleType`, `F_BizId`, `F_VersionNo`)' ); CALL sp_add_index_if_not_exists( 'lq_attendance_config_history', 'idx_attendance_config_history_time', 'ADD INDEX `idx_attendance_config_history_time` (`F_OperateTime`)' ); -- ======================================== -- 2. 考勤设置主表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_setting', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateTime`"); CALL sp_add_column_if_not_exists('lq_attendance_setting', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_setting', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_setting', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_setting', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 3. 公休日期表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_holiday', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_holiday', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_holiday', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_holiday', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_holiday', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 4. 考勤分组表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_group', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_group', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_group', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_group', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_group', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 5. 免考勤人员表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_exempt_user', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_exempt_user', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_exempt_user', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_exempt_user', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_exempt_user', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 6. 额外假期表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_extra_leave', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_extra_leave', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_extra_leave', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_extra_leave', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_extra_leave', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 7. 婚假规则表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_marriage_leave_rule', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateTime`"); CALL sp_add_column_if_not_exists('lq_attendance_marriage_leave_rule', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_marriage_leave_rule', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_marriage_leave_rule', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_marriage_leave_rule', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 8. 丧假规则表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_funeral_leave_rule', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateTime`"); CALL sp_add_column_if_not_exists('lq_attendance_funeral_leave_rule', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_funeral_leave_rule', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_funeral_leave_rule', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_funeral_leave_rule', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 9. 年假规则表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_annual_leave_rule', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateTime`"); CALL sp_add_column_if_not_exists('lq_attendance_annual_leave_rule', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_annual_leave_rule', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_annual_leave_rule', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_annual_leave_rule', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 10. 迟到早退规则表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_late_rule', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateTime`"); CALL sp_add_column_if_not_exists('lq_attendance_late_rule', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_late_rule', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_late_rule', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_late_rule', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 11. 缺卡规则表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_missing_card_rule', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateTime`"); CALL sp_add_column_if_not_exists('lq_attendance_missing_card_rule', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_missing_card_rule', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_missing_card_rule', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_missing_card_rule', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 12. 旷工规则表补字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_absenteeism_rule', 'F_DeleteMark', "int DEFAULT 0 COMMENT '逻辑删除标记(0-正常,1-已删除)' AFTER `F_CreateTime`"); CALL sp_add_column_if_not_exists('lq_attendance_absenteeism_rule', 'F_VersionNo', "int DEFAULT 0 COMMENT '当前版本号' AFTER `F_DeleteMark`"); CALL sp_add_column_if_not_exists('lq_attendance_absenteeism_rule', 'F_LastModifyUserId', "varchar(50) DEFAULT NULL COMMENT '最后修改人ID' AFTER `F_VersionNo`"); CALL sp_add_column_if_not_exists('lq_attendance_absenteeism_rule', 'F_LastModifyUserName', "varchar(100) DEFAULT NULL COMMENT '最后修改人姓名' AFTER `F_LastModifyUserId`"); CALL sp_add_column_if_not_exists('lq_attendance_absenteeism_rule', 'F_LastModifyTime', "datetime DEFAULT NULL COMMENT '最后修改时间' AFTER `F_LastModifyUserName`"); -- ======================================== -- 13. 打卡记录补规则快照字段 -- ======================================== CALL sp_add_column_if_not_exists('lq_attendance_record', 'F_RuleSnapshotJson', "longtext COMMENT '规则快照JSON' AFTER `F_Remark`"); DROP PROCEDURE IF EXISTS sp_add_column_if_not_exists; DROP PROCEDURE IF EXISTS sp_add_index_if_not_exists;