feat: 일일순회점검 시스템 구축 및 관리 기능 개선
- 일일순회점검 시스템 신규 구현 - DB 테이블: patrol_checklist_items, daily_patrol_sessions, patrol_check_records, workplace_items, item_types - API: /api/patrol/* 엔드포인트 - 프론트엔드: 지도 기반 작업장 점검 UI - 설비 관리 기능 개선 - 구매 관련 필드 추가 (구매일, 가격, 공급업체 등) - 설비 코드 자동 생성 (TKP-XXX 형식) - 작업장 관리 개선 - 레이아웃 이미지 업로드 기능 - 마커 위치 저장 기능 - 부서 관리 기능 추가 - 사이드바 네비게이션 카테고리 재구성 - 이미지 401 오류 수정 (정적 파일 경로 처리) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
295
api.hyungi.net/controllers/patrolController.js
Normal file
295
api.hyungi.net/controllers/patrolController.js
Normal file
@@ -0,0 +1,295 @@
|
||||
// patrolController.js
|
||||
// 일일순회점검 시스템 컨트롤러
|
||||
|
||||
const PatrolModel = require('../models/patrolModel');
|
||||
|
||||
const PatrolController = {
|
||||
// ==================== 순회점검 세션 ====================
|
||||
|
||||
// 세션 시작/조회
|
||||
getOrCreateSession: async (req, res) => {
|
||||
try {
|
||||
const { patrol_date, patrol_time, category_id } = req.body;
|
||||
const inspectorId = req.user.user_id;
|
||||
|
||||
if (!patrol_date || !patrol_time || !category_id) {
|
||||
return res.status(400).json({ success: false, message: '필수 정보가 누락되었습니다.' });
|
||||
}
|
||||
|
||||
const session = await PatrolModel.getOrCreateSession(patrol_date, patrol_time, category_id, inspectorId);
|
||||
res.json({ success: true, data: session });
|
||||
} catch (error) {
|
||||
console.error('세션 생성/조회 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 세션 상세 조회
|
||||
getSession: async (req, res) => {
|
||||
try {
|
||||
const { sessionId } = req.params;
|
||||
const session = await PatrolModel.getSession(sessionId);
|
||||
|
||||
if (!session) {
|
||||
return res.status(404).json({ success: false, message: '세션을 찾을 수 없습니다.' });
|
||||
}
|
||||
|
||||
res.json({ success: true, data: session });
|
||||
} catch (error) {
|
||||
console.error('세션 조회 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 세션 목록 조회
|
||||
getSessions: async (req, res) => {
|
||||
try {
|
||||
const { patrol_date, patrol_time, category_id, status, limit } = req.query;
|
||||
const sessions = await PatrolModel.getSessions({
|
||||
patrol_date,
|
||||
patrol_time,
|
||||
category_id,
|
||||
status,
|
||||
limit
|
||||
});
|
||||
res.json({ success: true, data: sessions });
|
||||
} catch (error) {
|
||||
console.error('세션 목록 조회 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 세션 완료
|
||||
completeSession: async (req, res) => {
|
||||
try {
|
||||
const { sessionId } = req.params;
|
||||
await PatrolModel.completeSession(sessionId);
|
||||
res.json({ success: true, message: '순회점검이 완료되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('세션 완료 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 세션 메모 업데이트
|
||||
updateSessionNotes: async (req, res) => {
|
||||
try {
|
||||
const { sessionId } = req.params;
|
||||
const { notes } = req.body;
|
||||
await PatrolModel.updateSessionNotes(sessionId, notes);
|
||||
res.json({ success: true, message: '메모가 저장되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('메모 저장 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 체크리스트 항목 ====================
|
||||
|
||||
// 체크리스트 항목 조회
|
||||
getChecklistItems: async (req, res) => {
|
||||
try {
|
||||
const { category_id, workplace_id } = req.query;
|
||||
const items = await PatrolModel.getChecklistItems(category_id, workplace_id);
|
||||
|
||||
// 카테고리별로 그룹화
|
||||
const grouped = {};
|
||||
items.forEach(item => {
|
||||
if (!grouped[item.check_category]) {
|
||||
grouped[item.check_category] = [];
|
||||
}
|
||||
grouped[item.check_category].push(item);
|
||||
});
|
||||
|
||||
res.json({ success: true, data: { items, grouped } });
|
||||
} catch (error) {
|
||||
console.error('체크리스트 항목 조회 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 체크리스트 항목 추가
|
||||
createChecklistItem: async (req, res) => {
|
||||
try {
|
||||
const itemId = await PatrolModel.createChecklistItem(req.body);
|
||||
res.json({ success: true, data: { item_id: itemId }, message: '항목이 추가되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('항목 추가 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 체크리스트 항목 수정
|
||||
updateChecklistItem: async (req, res) => {
|
||||
try {
|
||||
const { itemId } = req.params;
|
||||
await PatrolModel.updateChecklistItem(itemId, req.body);
|
||||
res.json({ success: true, message: '항목이 수정되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('항목 수정 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 체크리스트 항목 삭제
|
||||
deleteChecklistItem: async (req, res) => {
|
||||
try {
|
||||
const { itemId } = req.params;
|
||||
await PatrolModel.deleteChecklistItem(itemId);
|
||||
res.json({ success: true, message: '항목이 삭제되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('항목 삭제 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 체크 기록 ====================
|
||||
|
||||
// 작업장별 체크 기록 조회
|
||||
getCheckRecords: async (req, res) => {
|
||||
try {
|
||||
const { sessionId } = req.params;
|
||||
const { workplace_id } = req.query;
|
||||
const records = await PatrolModel.getCheckRecords(sessionId, workplace_id);
|
||||
res.json({ success: true, data: records });
|
||||
} catch (error) {
|
||||
console.error('체크 기록 조회 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 체크 기록 저장
|
||||
saveCheckRecord: async (req, res) => {
|
||||
try {
|
||||
const { sessionId } = req.params;
|
||||
const { workplace_id, check_item_id, is_checked, check_result, note } = req.body;
|
||||
|
||||
if (!workplace_id || !check_item_id) {
|
||||
return res.status(400).json({ success: false, message: '필수 정보가 누락되었습니다.' });
|
||||
}
|
||||
|
||||
await PatrolModel.saveCheckRecord(sessionId, workplace_id, check_item_id, is_checked, check_result, note);
|
||||
res.json({ success: true, message: '저장되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('체크 기록 저장 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 체크 기록 일괄 저장
|
||||
saveCheckRecords: async (req, res) => {
|
||||
try {
|
||||
const { sessionId } = req.params;
|
||||
const { workplace_id, records } = req.body;
|
||||
|
||||
if (!workplace_id || !records || !Array.isArray(records)) {
|
||||
return res.status(400).json({ success: false, message: '필수 정보가 누락되었습니다.' });
|
||||
}
|
||||
|
||||
await PatrolModel.saveCheckRecords(sessionId, workplace_id, records);
|
||||
res.json({ success: true, message: '저장되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('체크 기록 일괄 저장 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 작업장 물품 현황 ====================
|
||||
|
||||
// 작업장 물품 조회
|
||||
getWorkplaceItems: async (req, res) => {
|
||||
try {
|
||||
const { workplaceId } = req.params;
|
||||
const { include_inactive } = req.query;
|
||||
const items = await PatrolModel.getWorkplaceItems(workplaceId, include_inactive !== 'true');
|
||||
res.json({ success: true, data: items });
|
||||
} catch (error) {
|
||||
console.error('물품 조회 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 물품 추가
|
||||
createWorkplaceItem: async (req, res) => {
|
||||
try {
|
||||
const { workplaceId } = req.params;
|
||||
const data = { ...req.body, workplace_id: workplaceId, created_by: req.user.user_id };
|
||||
const itemId = await PatrolModel.createWorkplaceItem(data);
|
||||
res.json({ success: true, data: { item_id: itemId }, message: '물품이 추가되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('물품 추가 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 물품 수정
|
||||
updateWorkplaceItem: async (req, res) => {
|
||||
try {
|
||||
const { itemId } = req.params;
|
||||
await PatrolModel.updateWorkplaceItem(itemId, req.body, req.user.user_id);
|
||||
res.json({ success: true, message: '물품이 수정되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('물품 수정 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 물품 삭제
|
||||
deleteWorkplaceItem: async (req, res) => {
|
||||
try {
|
||||
const { itemId } = req.params;
|
||||
const { permanent } = req.query;
|
||||
|
||||
if (permanent === 'true') {
|
||||
await PatrolModel.hardDeleteWorkplaceItem(itemId);
|
||||
} else {
|
||||
await PatrolModel.deleteWorkplaceItem(itemId, req.user.user_id);
|
||||
}
|
||||
res.json({ success: true, message: '물품이 삭제되었습니다.' });
|
||||
} catch (error) {
|
||||
console.error('물품 삭제 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 물품 유형 ====================
|
||||
|
||||
// 물품 유형 목록
|
||||
getItemTypes: async (req, res) => {
|
||||
try {
|
||||
const types = await PatrolModel.getItemTypes();
|
||||
res.json({ success: true, data: types });
|
||||
} catch (error) {
|
||||
console.error('물품 유형 조회 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 대시보드/통계 ====================
|
||||
|
||||
// 오늘 순회점검 현황
|
||||
getTodayStatus: async (req, res) => {
|
||||
try {
|
||||
const { category_id } = req.query;
|
||||
const status = await PatrolModel.getTodayPatrolStatus(category_id);
|
||||
res.json({ success: true, data: status });
|
||||
} catch (error) {
|
||||
console.error('오늘 현황 조회 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
},
|
||||
|
||||
// 작업장별 점검 현황
|
||||
getWorkplaceCheckStatus: async (req, res) => {
|
||||
try {
|
||||
const { sessionId } = req.params;
|
||||
const status = await PatrolModel.getWorkplaceCheckStatus(sessionId);
|
||||
res.json({ success: true, data: status });
|
||||
} catch (error) {
|
||||
console.error('작업장별 점검 현황 조회 오류:', error);
|
||||
res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = PatrolController;
|
||||
Reference in New Issue
Block a user