feat: 설비 상세 패널 및 임시 이동 기능 구현

- 설비 마커 클릭 시 슬라이드 패널로 상세 정보 표시
- 설비 사진 업로드/삭제 기능
- 설비 임시 이동 기능 (3단계 지도 기반 선택)
  - Step 1: 공장 선택
  - Step 2: 레이아웃 지도에서 작업장 선택
  - Step 3: 상세 지도에서 위치 선택
- 설비 외부 반출/반입 기능
- 설비 수리 신청 기능 (기존 신고 시스템 연동)
- DB 마이그레이션 추가 (사진, 임시이동, 외부반출 테이블)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-02-04 13:45:56 +09:00
parent 90d3e32992
commit 4d83f10b07
13 changed files with 6043 additions and 74 deletions

View File

@@ -0,0 +1,17 @@
-- 설비 사진 테이블 생성
-- 실행: docker exec -i tkfb_db mysql -u hyungi -p'your_password' hyungi < db/migrations/20260205001000_create_equipment_photos.sql
CREATE TABLE IF NOT EXISTS equipment_photos (
photo_id INT AUTO_INCREMENT PRIMARY KEY,
equipment_id INT UNSIGNED NOT NULL,
photo_path VARCHAR(255) NOT NULL COMMENT '이미지 경로',
description VARCHAR(200) COMMENT '사진 설명',
display_order INT DEFAULT 0 COMMENT '표시 순서',
uploaded_by INT COMMENT '업로드한 사용자 ID',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_eq_photos_equipment FOREIGN KEY (equipment_id)
REFERENCES equipments(equipment_id) ON DELETE CASCADE,
CONSTRAINT fk_eq_photos_user FOREIGN KEY (uploaded_by)
REFERENCES users(user_id) ON DELETE SET NULL,
INDEX idx_eq_photos_equipment_id (equipment_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View File

@@ -0,0 +1,174 @@
-- 설비 임시이동 필드 추가 및 신고 시스템 연동
-- 실행: docker exec -i tkfb_db mysql -u hyungi -p'your_password' hyungi < db/migrations/20260205002000_add_equipment_move_fields.sql
SET @dbname = DATABASE();
-- ============================================
-- STEP 1: equipments 테이블에 임시이동 필드 추가
-- ============================================
-- current_workplace_id 컬럼 추가
SELECT COUNT(*) INTO @col_exists
FROM information_schema.columns
WHERE table_schema = @dbname AND table_name = 'equipments' AND column_name = 'current_workplace_id';
SET @sql = IF(@col_exists = 0,
'ALTER TABLE equipments ADD COLUMN current_workplace_id INT UNSIGNED NULL COMMENT ''현재 임시 위치 - 작업장 ID'' AFTER map_height_percent',
'SELECT ''current_workplace_id already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- current_map_x_percent 컬럼 추가
SELECT COUNT(*) INTO @col_exists
FROM information_schema.columns
WHERE table_schema = @dbname AND table_name = 'equipments' AND column_name = 'current_map_x_percent';
SET @sql = IF(@col_exists = 0,
'ALTER TABLE equipments ADD COLUMN current_map_x_percent DECIMAL(5,2) NULL COMMENT ''현재 위치 X%'' AFTER current_workplace_id',
'SELECT ''current_map_x_percent already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- current_map_y_percent 컬럼 추가
SELECT COUNT(*) INTO @col_exists
FROM information_schema.columns
WHERE table_schema = @dbname AND table_name = 'equipments' AND column_name = 'current_map_y_percent';
SET @sql = IF(@col_exists = 0,
'ALTER TABLE equipments ADD COLUMN current_map_y_percent DECIMAL(5,2) NULL COMMENT ''현재 위치 Y%'' AFTER current_map_x_percent',
'SELECT ''current_map_y_percent already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- current_map_width_percent 컬럼 추가
SELECT COUNT(*) INTO @col_exists
FROM information_schema.columns
WHERE table_schema = @dbname AND table_name = 'equipments' AND column_name = 'current_map_width_percent';
SET @sql = IF(@col_exists = 0,
'ALTER TABLE equipments ADD COLUMN current_map_width_percent DECIMAL(5,2) NULL COMMENT ''현재 위치 너비%'' AFTER current_map_y_percent',
'SELECT ''current_map_width_percent already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- current_map_height_percent 컬럼 추가
SELECT COUNT(*) INTO @col_exists
FROM information_schema.columns
WHERE table_schema = @dbname AND table_name = 'equipments' AND column_name = 'current_map_height_percent';
SET @sql = IF(@col_exists = 0,
'ALTER TABLE equipments ADD COLUMN current_map_height_percent DECIMAL(5,2) NULL COMMENT ''현재 위치 높이%'' AFTER current_map_width_percent',
'SELECT ''current_map_height_percent already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- is_temporarily_moved 컬럼 추가
SELECT COUNT(*) INTO @col_exists
FROM information_schema.columns
WHERE table_schema = @dbname AND table_name = 'equipments' AND column_name = 'is_temporarily_moved';
SET @sql = IF(@col_exists = 0,
'ALTER TABLE equipments ADD COLUMN is_temporarily_moved BOOLEAN DEFAULT FALSE COMMENT ''임시 이동 상태'' AFTER current_map_height_percent',
'SELECT ''is_temporarily_moved already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- moved_at 컬럼 추가
SELECT COUNT(*) INTO @col_exists
FROM information_schema.columns
WHERE table_schema = @dbname AND table_name = 'equipments' AND column_name = 'moved_at';
SET @sql = IF(@col_exists = 0,
'ALTER TABLE equipments ADD COLUMN moved_at DATETIME NULL COMMENT ''이동 일시'' AFTER is_temporarily_moved',
'SELECT ''moved_at already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- moved_by 컬럼 추가
SELECT COUNT(*) INTO @col_exists
FROM information_schema.columns
WHERE table_schema = @dbname AND table_name = 'equipments' AND column_name = 'moved_by';
SET @sql = IF(@col_exists = 0,
'ALTER TABLE equipments ADD COLUMN moved_by INT NULL COMMENT ''이동 처리자'' AFTER moved_at',
'SELECT ''moved_by already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- Foreign Key: current_workplace_id -> workplaces
SELECT COUNT(*) INTO @fk_exists
FROM information_schema.table_constraints
WHERE table_schema = @dbname AND table_name = 'equipments' AND constraint_name = 'fk_eq_current_workplace';
SET @sql = IF(@fk_exists = 0,
'ALTER TABLE equipments ADD CONSTRAINT fk_eq_current_workplace FOREIGN KEY (current_workplace_id) REFERENCES workplaces(workplace_id) ON DELETE SET NULL',
'SELECT ''fk_eq_current_workplace already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SELECT 'equipments 임시이동 필드 추가 완료' AS status;
-- ============================================
-- STEP 2: work_issue_reports에 equipment_id 필드 추가
-- ============================================
SELECT COUNT(*) INTO @col_exists
FROM information_schema.columns
WHERE table_schema = @dbname AND table_name = 'work_issue_reports' AND column_name = 'equipment_id';
SET @sql = IF(@col_exists = 0,
'ALTER TABLE work_issue_reports ADD COLUMN equipment_id INT UNSIGNED NULL COMMENT ''관련 설비 ID'' AFTER visit_request_id',
'SELECT ''equipment_id already exists in work_issue_reports''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- Foreign Key
SELECT COUNT(*) INTO @fk_exists
FROM information_schema.table_constraints
WHERE table_schema = @dbname AND table_name = 'work_issue_reports' AND constraint_name = 'fk_wir_equipment';
SET @sql = IF(@fk_exists = 0 AND @col_exists = 0,
'ALTER TABLE work_issue_reports ADD CONSTRAINT fk_wir_equipment FOREIGN KEY (equipment_id) REFERENCES equipments(equipment_id) ON DELETE SET NULL',
'SELECT ''fk_wir_equipment already exists or column not added''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- Index
SELECT COUNT(*) INTO @idx_exists
FROM information_schema.statistics
WHERE table_schema = @dbname AND table_name = 'work_issue_reports' AND index_name = 'idx_wir_equipment_id';
SET @sql = IF(@idx_exists = 0 AND @col_exists = 0,
'ALTER TABLE work_issue_reports ADD INDEX idx_wir_equipment_id (equipment_id)',
'SELECT ''idx_wir_equipment_id already exists''');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SELECT 'work_issue_reports equipment_id 추가 완료' AS status;
-- ============================================
-- STEP 3: 설비 수리 카테고리 추가
-- ============================================
INSERT INTO issue_report_categories (category_type, category_name, description, display_order, is_active)
SELECT 'nonconformity', '설비 수리', '설비 고장 및 수리 요청', 10, 1
WHERE NOT EXISTS (
SELECT 1 FROM issue_report_categories WHERE category_name = '설비 수리'
);
-- 설비 수리 카테고리에 기본 항목 추가
SET @category_id = (SELECT category_id FROM issue_report_categories WHERE category_name = '설비 수리' LIMIT 1);
INSERT INTO issue_report_items (category_id, item_name, description, severity, display_order, is_active)
SELECT @category_id, '기계 고장', '기계 작동 불가 또는 이상', 'high', 1, 1
WHERE @category_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM issue_report_items WHERE category_id = @category_id AND item_name = '기계 고장'
);
INSERT INTO issue_report_items (category_id, item_name, description, severity, display_order, is_active)
SELECT @category_id, '부품 교체 필요', '소모품 또는 부품 교체 필요', 'medium', 2, 1
WHERE @category_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM issue_report_items WHERE category_id = @category_id AND item_name = '부품 교체 필요'
);
INSERT INTO issue_report_items (category_id, item_name, description, severity, display_order, is_active)
SELECT @category_id, '정기 점검 필요', '예방 정비 또는 정기 점검', 'low', 3, 1
WHERE @category_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM issue_report_items WHERE category_id = @category_id AND item_name = '정기 점검 필요'
);
INSERT INTO issue_report_items (category_id, item_name, description, severity, display_order, is_active)
SELECT @category_id, '외부 수리 필요', '전문 업체 수리가 필요한 경우', 'high', 4, 1
WHERE @category_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM issue_report_items WHERE category_id = @category_id AND item_name = '외부 수리 필요'
);
SELECT '설비 수리 카테고리 및 항목 추가 완료' AS status;

View File

@@ -0,0 +1,86 @@
-- 설비 외부반출 테이블 생성 및 상태 ENUM 확장
-- 실행: docker exec -i tkfb_db mysql -u hyungi -p'your_password' hyungi < db/migrations/20260205003000_create_equipment_external_logs.sql
SET @dbname = DATABASE();
-- ============================================
-- STEP 1: equipment_external_logs 테이블 생성
-- ============================================
CREATE TABLE IF NOT EXISTS equipment_external_logs (
log_id INT AUTO_INCREMENT PRIMARY KEY,
equipment_id INT UNSIGNED NOT NULL COMMENT '설비 ID',
log_type ENUM('export', 'return') NOT NULL COMMENT '반출/반입',
export_date DATE COMMENT '반출일',
expected_return_date DATE COMMENT '반입 예정일',
actual_return_date DATE COMMENT '실제 반입일',
destination VARCHAR(200) COMMENT '반출처 (수리업체명 등)',
reason TEXT COMMENT '반출 사유',
notes TEXT COMMENT '비고',
exported_by INT COMMENT '반출 담당자',
returned_by INT COMMENT '반입 담당자',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_eel_equipment FOREIGN KEY (equipment_id)
REFERENCES equipments(equipment_id) ON DELETE CASCADE,
CONSTRAINT fk_eel_exported_by FOREIGN KEY (exported_by)
REFERENCES users(user_id) ON DELETE SET NULL,
CONSTRAINT fk_eel_returned_by FOREIGN KEY (returned_by)
REFERENCES users(user_id) ON DELETE SET NULL,
INDEX idx_eel_equipment_id (equipment_id),
INDEX idx_eel_log_type (log_type),
INDEX idx_eel_export_date (export_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SELECT 'equipment_external_logs 테이블 생성 완료' AS status;
-- ============================================
-- STEP 2: equipments 테이블 status ENUM 확장
-- ============================================
-- 현재 status 컬럼의 ENUM 값 확인 후 확장
-- 기존: active, maintenance, repair_needed, inactive
-- 추가: external (외부 반출), repair_external (수리 외주)
ALTER TABLE equipments
MODIFY COLUMN status ENUM(
'active', -- 정상 가동
'maintenance', -- 점검 중
'repair_needed', -- 수리 필요
'inactive', -- 비활성
'external', -- 외부 반출
'repair_external' -- 수리 외주 (외부 수리)
) DEFAULT 'active' COMMENT '설비 상태';
SELECT 'equipments status ENUM 확장 완료' AS status;
-- ============================================
-- STEP 3: 설비 이동 이력 테이블 생성 (선택)
-- ============================================
CREATE TABLE IF NOT EXISTS equipment_move_logs (
log_id INT AUTO_INCREMENT PRIMARY KEY,
equipment_id INT UNSIGNED NOT NULL COMMENT '설비 ID',
move_type ENUM('temporary', 'return') NOT NULL COMMENT '임시이동/복귀',
from_workplace_id INT UNSIGNED COMMENT '이전 작업장',
to_workplace_id INT UNSIGNED COMMENT '이동 작업장',
from_x_percent DECIMAL(5,2) COMMENT '이전 X좌표',
from_y_percent DECIMAL(5,2) COMMENT '이전 Y좌표',
to_x_percent DECIMAL(5,2) COMMENT '이동 X좌표',
to_y_percent DECIMAL(5,2) COMMENT '이동 Y좌표',
reason TEXT COMMENT '이동 사유',
moved_by INT COMMENT '이동 처리자',
moved_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_eml_equipment FOREIGN KEY (equipment_id)
REFERENCES equipments(equipment_id) ON DELETE CASCADE,
CONSTRAINT fk_eml_from_workplace FOREIGN KEY (from_workplace_id)
REFERENCES workplaces(workplace_id) ON DELETE SET NULL,
CONSTRAINT fk_eml_to_workplace FOREIGN KEY (to_workplace_id)
REFERENCES workplaces(workplace_id) ON DELETE SET NULL,
CONSTRAINT fk_eml_moved_by FOREIGN KEY (moved_by)
REFERENCES users(user_id) ON DELETE SET NULL,
INDEX idx_eml_equipment_id (equipment_id),
INDEX idx_eml_move_type (move_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SELECT 'equipment_move_logs 테이블 생성 완료' AS status;