diff --git a/system1-factory/api/controllers/equipmentController.js b/system1-factory/api/controllers/equipmentController.js index 2ceb301..6cd7c9e 100644 --- a/system1-factory/api/controllers/equipmentController.js +++ b/system1-factory/api/controllers/equipmentController.js @@ -558,6 +558,19 @@ const EquipmentController = { } }, + getRepairRequests: async (req, res) => { + try { + const results = await EquipmentModel.getRepairRequests(req.query.status || null); + res.json({ success: true, data: results }); + } catch (err) { + logger.error('수리 요청 목록 조회 오류:', err); + res.status(500).json({ + success: false, + message: '수리 요청 목록 조회 중 오류가 발생했습니다.' + }); + } + }, + getRepairCategories: async (req, res) => { try { const results = await EquipmentModel.getRepairCategories(); diff --git a/system1-factory/api/models/equipmentModel.js b/system1-factory/api/models/equipmentModel.js index f3cc31d..1069dea 100644 --- a/system1-factory/api/models/equipmentModel.js +++ b/system1-factory/api/models/equipmentModel.js @@ -710,6 +710,33 @@ const EquipmentModel = { return rows; }, + getRepairRequests: async (status) => { + const db = await getDb(); + let query = ` + SELECT wir.report_id, wir.status, wir.additional_description, wir.created_at, + e.equipment_name, irc.category_name, iri.item_name, + u_rep.name AS reported_by_name, w.workplace_name + FROM work_issue_reports wir + INNER JOIN issue_report_categories irc ON wir.issue_category_id = irc.category_id + LEFT JOIN issue_report_items iri ON wir.issue_item_id = iri.item_id + LEFT JOIN equipments e ON wir.equipment_id = e.equipment_id + LEFT JOIN users u_rep ON wir.reporter_id = u_rep.user_id + LEFT JOIN workplaces w ON wir.workplace_id = w.workplace_id + WHERE irc.category_name = '설비 수리' + `; + const values = []; + + if (status) { + query += ' AND wir.status = ?'; + values.push(status); + } + + query += ' ORDER BY wir.created_at DESC'; + + const [rows] = await db.query(query, values); + return rows; + }, + getRepairCategories: async () => { const db = await getDb(); const [rows] = await db.query( diff --git a/system1-factory/api/routes/equipmentRoutes.js b/system1-factory/api/routes/equipmentRoutes.js index 53f16b9..183d822 100644 --- a/system1-factory/api/routes/equipmentRoutes.js +++ b/system1-factory/api/routes/equipmentRoutes.js @@ -46,6 +46,9 @@ router.get('/repair-categories', equipmentController.getRepairCategories); // 새 수리 항목 추가 router.post('/repair-categories', equipmentController.addRepairCategory); +// 수리 요청 목록 조회 (?status=pending) +router.get('/repair-requests', equipmentController.getRepairRequests); + // ==================== 사진 관리 ==================== // 사진 삭제 (설비 ID 없이 photo_id만으로) diff --git a/system1-factory/web/pages/dashboard-new.html b/system1-factory/web/pages/dashboard-new.html index 9d32117..aaf4331 100644 --- a/system1-factory/web/pages/dashboard-new.html +++ b/system1-factory/web/pages/dashboard-new.html @@ -65,8 +65,8 @@
수리 요청
-
-
-
미확인 알림
+
+
알림 관리
@@ -139,6 +139,6 @@ - + diff --git a/system1-factory/web/static/js/tkfb-dashboard.js b/system1-factory/web/static/js/tkfb-dashboard.js index df35e2a..7a04115 100644 --- a/system1-factory/web/static/js/tkfb-dashboard.js +++ b/system1-factory/web/static/js/tkfb-dashboard.js @@ -16,30 +16,28 @@ async function loadDashboard() { const results = await Promise.allSettled([ api('/tbm/sessions/date/' + today).catch(() => ({ data: [] })), - api('/notifications/unread').catch(() => ({ data: [] })), api('/equipments/repair-requests?status=pending').catch(() => ({ data: [] })), - api('/attendance/today-summary').catch(() => ({ data: {} })), + api('/attendance/daily-status?date=' + today).catch(() => ({ data: [] })), ]); const tbmData = results[0].status === 'fulfilled' ? results[0].value : { data: [] }; - const notifData = results[1].status === 'fulfilled' ? results[1].value : { data: [] }; - const repairData = results[2].status === 'fulfilled' ? results[2].value : { data: [] }; - const attendData = results[3].status === 'fulfilled' ? results[3].value : { data: {} }; + const repairData = results[1].status === 'fulfilled' ? results[1].value : { data: [] }; + const attendData = results[2].status === 'fulfilled' ? results[2].value : { data: [] }; const tbmSessions = tbmData.data || []; - const notifications = notifData.data || []; const repairs = repairData.data || []; - const attendance = attendData.data || {}; + const attendList = Array.isArray(attendData.data) ? attendData.data : []; + const checkedInCount = attendList.filter(d => d.status !== 'incomplete').length; // Stats document.getElementById('statTbm').textContent = tbmSessions.length; - document.getElementById('statWorkers').textContent = attendance.checked_in_count || 0; + document.getElementById('statWorkers').textContent = checkedInCount; document.getElementById('statRepairs').textContent = repairs.length; - document.getElementById('statNotifications').textContent = notifications.length; + document.getElementById('statNotifications').textContent = '-'; // TBM list renderTbmList(tbmSessions); - renderNotificationList(notifications); + renderNotificationPanel(); renderRepairList(repairs); } @@ -64,23 +62,15 @@ function renderTbmList(sessions) { } } -function renderNotificationList(notifications) { +function renderNotificationPanel() { const el = document.getElementById('notificationList'); - if (!notifications.length) { - el.innerHTML = '

새 알림이 없습니다

'; - return; - } - const icons = { repair: 'fa-wrench text-amber-500', safety: 'fa-shield-alt text-red-500', system: 'fa-bell text-blue-500', equipment: 'fa-cog text-gray-500', maintenance: 'fa-tools text-green-500' }; - el.innerHTML = notifications.slice(0, 5).map(n => { - const iconClass = icons[n.type] || 'fa-bell text-gray-400'; - return `
- -
-
${escapeHtml(n.title)}
-
${formatTimeAgo(n.created_at)}
-
-
`; - }).join(''); + el.innerHTML = `
+ +

알림은 사용자관리에서 확인하세요

+ + 알림 관리 바로가기 + +
`; } function renderRepairList(repairs) {