Files
TK-FB-Project/api.hyungi.net/routes/userRoutes.js
Hyungi Ahn b6485e3140 feat: 대시보드 작업장 현황 지도 구현
- 실시간 작업장 현황을 지도로 시각화
- 작업장 관리 페이지에서 정의한 구역 정보 활용
- TBM 작업자 및 방문자 현황 표시

주요 변경사항:
- dashboard.html: 작업장 현황 섹션 추가 (기존 작업 현황 테이블 제거)
- workplace-status.js: 지도 렌더링 및 데이터 통합 로직 구현
- modern-dashboard.js: 삭제된 DOM 요소 조건부 체크 추가

시각화 방식:
- 인원 없음: 회색 테두리 + 작업장 이름
- 내부 작업자: 파란색 영역 + 인원 수
- 외부 방문자: 보라색 영역 + 인원 수
- 둘 다: 초록색 영역 + 총 인원 수

기술 구현:
- Canvas API 기반 사각형 영역 렌더링
- map-regions API를 통한 데이터 일관성 보장
- 클릭 이벤트로 상세 정보 모달 표시

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-29 15:46:47 +09:00

138 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 사용자 관리 라우터
*
* 사용자 CRUD 및 상태 관리를 위한 API 라우트 정의
*
* @author TK-FB-Project
* @since 2025-12-11
*/
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
const { verifyToken } = require('../middlewares/authMiddleware');
const logger = require('../utils/logger');
/**
* 모든 라우트에 인증 미들웨어 적용
*/
router.use(verifyToken);
/**
* 관리자 권한 확인 미들웨어
*/
const adminOnly = (req, res, next) => {
const userRole = req.user?.role?.toLowerCase();
if (req.user && (userRole === 'admin' || userRole === 'system' || userRole === 'system admin')) {
next();
} else {
logger.warn('관리자 권한 없는 접근 시도', {
userId: req.user?.user_id,
username: req.user?.username,
role: req.user?.role,
url: req.originalUrl
});
return res.status(403).json({
success: false,
message: '관리자 권한이 필요합니다'
});
}
};
// ========== 개인 정보 조회 API (관리자 권한 불필요) ==========
// 내 정보 조회
router.get('/me', userController.getMyInfo || ((req, res) => res.json({ success: true, data: req.user })));
// 내 출근 기록 조회
router.get('/me/attendance-records', async (req, res) => {
try {
const { year, month } = req.query;
const AttendanceModel = require('../models/attendanceModel');
const startDate = `${year}-${String(month).padStart(2, '0')}-01`;
const endDate = `${year}-${String(month).padStart(2, '0')}-31`;
const records = await AttendanceModel.getDailyRecords(startDate, endDate, req.user.worker_id);
res.json({ success: true, data: records });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// 내 연차 잔액 조회
router.get('/me/vacation-balance', async (req, res) => {
try {
const AttendanceModel = require('../models/attendanceModel');
const year = req.query.year || new Date().getFullYear();
const balance = await AttendanceModel.getWorkerVacationBalance(req.user.worker_id, year);
res.json({ success: true, data: balance });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// 내 작업 보고서 조회
router.get('/me/work-reports', async (req, res) => {
try {
const { startDate, endDate } = req.query;
const db = require('../config/database');
const reports = await db.query(
'SELECT * FROM daily_work_reports WHERE worker_id = ? AND report_date BETWEEN ? AND ? ORDER BY report_date DESC',
[req.user.worker_id, startDate, endDate]
);
res.json({ success: true, data: reports });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// 내 월별 통계
router.get('/me/monthly-stats', async (req, res) => {
try {
const { year, month } = req.query;
const { getDb } = require('../dbPool');
const db = await getDb();
const [stats] = await db.execute(
`SELECT
SUM(total_work_hours) as month_hours,
COUNT(DISTINCT record_date) as work_days
FROM daily_attendance_records
WHERE worker_id = ? AND YEAR(record_date) = ? AND MONTH(record_date) = ?`,
[req.user.worker_id, year, month]
);
res.json({ success: true, data: stats[0] || { month_hours: 0, work_days: 0 } });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// ========== 관리자 전용 API ==========
/**
* 모든 라우트에 관리자 권한 적용
*/
router.use(adminOnly);
// 📋 사용자 목록 조회
router.get('/', userController.getAllUsers);
// 👤 특정 사용자 조회
router.get('/:id', userController.getUserById);
// 새 사용자 생성
router.post('/', userController.createUser);
// ✏️ 사용자 정보 수정
router.put('/:id', userController.updateUser);
// 🔄 사용자 상태 변경
router.put('/:id/status', userController.updateUserStatus);
// 🗑️ 사용자 삭제
router.delete('/:id', userController.deleteUser);
// 📄 사용자 페이지 접근 권한 조회
router.get('/:id/page-access', userController.getUserPageAccess);
// 🔐 사용자 페이지 접근 권한 업데이트
router.put('/:id/page-access', userController.updateUserPageAccess);
module.exports = router;