- 월별 캘린더 UI로 작업 현황을 한눈에 확인 가능 - 미입력(빨강), 부분입력(주황), 확인필요(보라), 이상없음(초록) 상태 표시 - 범례 아이콘(●)을 사용한 직관적인 상태 표시 - 날짜 클릭 시 해당일 작업자별 상세 현황 모달 - 작업자 클릭 시 개별 작업 입력/수정 모달 - 휴가 처리 기능 (연차, 반차, 반반차, 조퇴) - 월별 집계 데이터 최적화로 API 호출 최소화 백엔드: - monthly_worker_status, monthly_summary 테이블 추가 - 자동 집계 stored procedure 및 trigger 구현 - 확인필요(12시간 초과) 상태 감지 로직 - 출석 관리 시스템 확장 프론트엔드: - 캘린더 그리드 UI 구현 - 상태별 색상 및 아이콘 표시 - 모달 기반 상세 정보 표시 - 반응형 디자인 적용
144 lines
7.0 KiB
SQL
144 lines
7.0 KiB
SQL
-- 근태 관리 시스템 테이블 추가
|
|
-- 작성일: 2025-11-03
|
|
-- 설명: 근로 유형, 휴가 유형, 일일 근태 기록, 휴가 잔여 관리 테이블
|
|
|
|
-- 1. 근로 유형 테이블 생성
|
|
CREATE TABLE IF NOT EXISTS `work_attendance_types` (
|
|
`id` INT PRIMARY KEY AUTO_INCREMENT,
|
|
`type_code` VARCHAR(20) NOT NULL UNIQUE COMMENT '근로 유형 코드',
|
|
`type_name` VARCHAR(50) NOT NULL COMMENT '근로 유형명',
|
|
`description` TEXT COMMENT '설명',
|
|
`is_active` BOOLEAN DEFAULT TRUE COMMENT '활성 상태',
|
|
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='근로 유형 관리 테이블';
|
|
|
|
-- 2. 휴가 유형 테이블 생성
|
|
CREATE TABLE IF NOT EXISTS `vacation_types` (
|
|
`id` INT PRIMARY KEY AUTO_INCREMENT,
|
|
`type_code` VARCHAR(20) NOT NULL UNIQUE COMMENT '휴가 유형 코드',
|
|
`type_name` VARCHAR(50) NOT NULL COMMENT '휴가 유형명',
|
|
`hours_deduction` DECIMAL(4,2) NOT NULL COMMENT '차감 시간',
|
|
`description` TEXT COMMENT '설명',
|
|
`is_active` BOOLEAN DEFAULT TRUE COMMENT '활성 상태',
|
|
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='휴가 유형 관리 테이블';
|
|
|
|
-- 3. 일일 근태 기록 테이블 생성
|
|
CREATE TABLE IF NOT EXISTS `daily_attendance_records` (
|
|
`id` INT PRIMARY KEY AUTO_INCREMENT,
|
|
`record_date` DATE NOT NULL COMMENT '기록 날짜',
|
|
`worker_id` INT NOT NULL COMMENT '작업자 ID',
|
|
`total_work_hours` DECIMAL(4,2) DEFAULT 0 COMMENT '총 작업 시간',
|
|
`attendance_type_id` INT COMMENT '근로 유형 ID',
|
|
`vacation_type_id` INT NULL COMMENT '휴가 유형 ID',
|
|
`is_vacation_processed` BOOLEAN DEFAULT FALSE COMMENT '휴가 처리 여부',
|
|
`overtime_approved` BOOLEAN DEFAULT FALSE COMMENT '초과근무 승인 여부',
|
|
`overtime_approved_by` INT NULL COMMENT '초과근무 승인자 ID',
|
|
`overtime_approved_at` TIMESTAMP NULL COMMENT '초과근무 승인 시간',
|
|
`status` ENUM('incomplete', 'partial', 'complete', 'overtime', 'vacation', 'error') DEFAULT 'incomplete' COMMENT '상태',
|
|
`notes` TEXT COMMENT '비고',
|
|
`created_by` INT NOT NULL DEFAULT 1 COMMENT '생성자 ID',
|
|
`updated_by` INT NULL COMMENT '수정자 ID',
|
|
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
|
-- 인덱스
|
|
UNIQUE KEY `unique_worker_date` (`worker_id`, `record_date`),
|
|
INDEX `idx_record_date` (`record_date`),
|
|
INDEX `idx_worker_date` (`worker_id`, `record_date`),
|
|
INDEX `idx_status` (`status`),
|
|
|
|
-- 외래키 (기존 테이블과의 관계)
|
|
FOREIGN KEY (`worker_id`) REFERENCES `workers`(`worker_id`) ON DELETE CASCADE,
|
|
FOREIGN KEY (`attendance_type_id`) REFERENCES `work_attendance_types`(`id`),
|
|
FOREIGN KEY (`vacation_type_id`) REFERENCES `vacation_types`(`id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='일일 근태 기록 테이블';
|
|
|
|
-- 4. 작업자 휴가 잔여 관리 테이블 생성
|
|
CREATE TABLE IF NOT EXISTS `worker_vacation_balance` (
|
|
`id` INT PRIMARY KEY AUTO_INCREMENT,
|
|
`worker_id` INT NOT NULL COMMENT '작업자 ID',
|
|
`year` YEAR NOT NULL COMMENT '연도',
|
|
`total_annual_leave` DECIMAL(4,2) DEFAULT 15.0 COMMENT '연간 총 연차 (일)',
|
|
`used_annual_leave` DECIMAL(4,2) DEFAULT 0 COMMENT '사용한 연차 (일)',
|
|
`remaining_annual_leave` DECIMAL(4,2) GENERATED ALWAYS AS (`total_annual_leave` - `used_annual_leave`) STORED COMMENT '잔여 연차 (일)',
|
|
`notes` TEXT COMMENT '비고',
|
|
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
|
-- 인덱스
|
|
UNIQUE KEY `unique_worker_year` (`worker_id`, `year`),
|
|
INDEX `idx_worker_year` (`worker_id`, `year`),
|
|
|
|
-- 외래키
|
|
FOREIGN KEY (`worker_id`) REFERENCES `workers`(`worker_id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='작업자별 휴가 잔여 관리 테이블';
|
|
|
|
-- 5. daily_work_reports 테이블에 근태 기록 연결 컬럼 추가
|
|
ALTER TABLE `daily_work_reports`
|
|
ADD COLUMN IF NOT EXISTS `attendance_record_id` INT NULL COMMENT '근태 기록 ID' AFTER `updated_by`;
|
|
|
|
-- 인덱스 추가
|
|
CREATE INDEX IF NOT EXISTS `idx_attendance_record` ON `daily_work_reports`(`attendance_record_id`);
|
|
CREATE INDEX IF NOT EXISTS `idx_daily_work_reports_worker_date` ON `daily_work_reports`(`worker_id`, `report_date`);
|
|
|
|
-- 6. 기본 데이터 삽입
|
|
|
|
-- 근로 유형 기본 데이터
|
|
INSERT IGNORE INTO `work_attendance_types` (`type_code`, `type_name`, `description`) VALUES
|
|
('REGULAR', '정시근로', '8시간 정규 근무'),
|
|
('OVERTIME', '연장근로', '8시간 초과 근무'),
|
|
('PARTIAL', '부분근로', '8시간 미만 근무'),
|
|
('VACATION', '휴가근로', '휴가와 함께하는 부분 근무');
|
|
|
|
-- 휴가 유형 기본 데이터
|
|
INSERT IGNORE INTO `vacation_types` (`type_code`, `type_name`, `hours_deduction`, `description`) VALUES
|
|
('ANNUAL_FULL', '연차', 8.0, '하루 전체 연차'),
|
|
('ANNUAL_HALF', '반차', 4.0, '반일 연차'),
|
|
('ANNUAL_QUARTER', '반반차', 2.0, '1/4일 연차'),
|
|
('SICK_FULL', '병가', 8.0, '하루 전체 병가'),
|
|
('SICK_HALF', '반일병가', 4.0, '반일 병가'),
|
|
('PERSONAL_FULL', '개인사유', 8.0, '개인사유로 인한 휴가'),
|
|
('PERSONAL_HALF', '반일개인사유', 4.0, '반일 개인사유 휴가');
|
|
|
|
-- 7. 휴가 전용 작업 유형 추가 (이미 있으면 무시)
|
|
INSERT IGNORE INTO `work_types` (`name`, `description`, `is_active`) VALUES
|
|
('휴가', '연차, 반차, 병가 등 휴가 처리용', TRUE);
|
|
|
|
-- 8. 뷰 생성 - 일일 근태 현황 조회용
|
|
CREATE OR REPLACE VIEW `v_daily_attendance_summary` AS
|
|
SELECT
|
|
dar.id,
|
|
dar.record_date,
|
|
dar.worker_id,
|
|
w.worker_name,
|
|
w.job_type,
|
|
dar.total_work_hours,
|
|
wat.type_name as attendance_type,
|
|
vt.type_name as vacation_type,
|
|
dar.is_vacation_processed,
|
|
dar.overtime_approved,
|
|
dar.status,
|
|
CASE
|
|
WHEN dar.status = 'incomplete' THEN '미입력'
|
|
WHEN dar.status = 'partial' THEN '부분입력'
|
|
WHEN dar.status = 'complete' THEN '정시근로'
|
|
WHEN dar.status = 'overtime' THEN '연장근로'
|
|
WHEN dar.status = 'vacation' THEN '휴가'
|
|
WHEN dar.status = 'error' THEN '오류'
|
|
ELSE '알수없음'
|
|
END as status_text,
|
|
dar.notes,
|
|
dar.created_at,
|
|
dar.updated_at
|
|
FROM daily_attendance_records dar
|
|
LEFT JOIN workers w ON dar.worker_id = w.worker_id
|
|
LEFT JOIN work_attendance_types wat ON dar.attendance_type_id = wat.id
|
|
LEFT JOIN vacation_types vt ON dar.vacation_type_id = vt.id
|
|
ORDER BY dar.record_date DESC, w.worker_name;
|
|
|
|
-- 완료 메시지
|
|
SELECT '✅ 근태 관리 시스템 테이블이 성공적으로 생성되었습니다.' as message;
|