feat: tkuser 통합 관리 서비스 + 전체 시스템 SSO 쿠키 인증 통합
- tkuser 서비스 신규 추가 (API + Web) - 사용자/권한/프로젝트/부서/작업자/작업장/설비/작업/휴가 통합 관리 - 작업장 탭: 공장→작업장 드릴다운 네비게이션 + 구역지도 클릭 연동 - 작업 탭: 공정(work_types)→작업(tasks) 계층 관리 - 휴가 탭: 유형 관리 + 연차 배정(근로기준법 자동계산) - 전 시스템 SSO 쿠키 인증으로 통합 (.technicalkorea.net 공유) - System 2: 작업 이슈 리포트 기능 강화 - System 3: tkuser API 연동, 페이지 권한 체계 적용 - docker-compose에 tkuser-api, tkuser-web 서비스 추가 - ARCHITECTURE.md, DEPLOYMENT.md 문서 작성 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
141
user-management/api/controllers/equipmentController.js
Normal file
141
user-management/api/controllers/equipmentController.js
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Equipment Controller
|
||||
*
|
||||
* 설비 CRUD + 지도위치 + 사진
|
||||
*/
|
||||
|
||||
const equipmentModel = require('../models/equipmentModel');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
// ==================== 기본 CRUD ====================
|
||||
|
||||
async function getAll(req, res, next) {
|
||||
try {
|
||||
const filters = {};
|
||||
if (req.query.workplace_id) filters.workplace_id = parseInt(req.query.workplace_id);
|
||||
if (req.query.equipment_type) filters.equipment_type = req.query.equipment_type;
|
||||
if (req.query.status) filters.status = req.query.status;
|
||||
if (req.query.search) filters.search = req.query.search;
|
||||
const equipments = await equipmentModel.getAll(filters);
|
||||
res.json({ success: true, data: equipments });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
async function getById(req, res, next) {
|
||||
try {
|
||||
const eq = await equipmentModel.getById(parseInt(req.params.id));
|
||||
if (!eq) return res.status(404).json({ success: false, error: '설비를 찾을 수 없습니다' });
|
||||
res.json({ success: true, data: eq });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
async function getByWorkplace(req, res, next) {
|
||||
try {
|
||||
const equipments = await equipmentModel.getByWorkplace(parseInt(req.params.workplaceId));
|
||||
res.json({ success: true, data: equipments });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
async function create(req, res, next) {
|
||||
try {
|
||||
const { equipment_code, equipment_name } = req.body;
|
||||
if (!equipment_code || !equipment_name) return res.status(400).json({ success: false, error: '관리번호와 설비명은 필수입니다' });
|
||||
const dup = await equipmentModel.checkDuplicateCode(equipment_code);
|
||||
if (dup) return res.status(409).json({ success: false, error: '이미 존재하는 관리번호입니다' });
|
||||
const eq = await equipmentModel.create(req.body);
|
||||
res.status(201).json({ success: true, data: eq });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
async function update(req, res, next) {
|
||||
try {
|
||||
const id = parseInt(req.params.id);
|
||||
if (req.body.equipment_code) {
|
||||
const dup = await equipmentModel.checkDuplicateCode(req.body.equipment_code, id);
|
||||
if (dup) return res.status(409).json({ success: false, error: '이미 존재하는 관리번호입니다' });
|
||||
}
|
||||
const eq = await equipmentModel.update(id, req.body);
|
||||
if (!eq) return res.status(404).json({ success: false, error: '설비를 찾을 수 없습니다' });
|
||||
res.json({ success: true, data: eq });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
async function remove(req, res, next) {
|
||||
try {
|
||||
await equipmentModel.remove(parseInt(req.params.id));
|
||||
res.json({ success: true, message: '설비가 삭제되었습니다' });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
async function getTypes(req, res, next) {
|
||||
try {
|
||||
const types = await equipmentModel.getEquipmentTypes();
|
||||
res.json({ success: true, data: types });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
async function getNextCode(req, res, next) {
|
||||
try {
|
||||
const code = await equipmentModel.getNextCode(req.query.prefix || 'TKP');
|
||||
res.json({ success: true, data: code });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
// ==================== 지도 위치 ====================
|
||||
|
||||
async function updateMapPosition(req, res, next) {
|
||||
try {
|
||||
const id = parseInt(req.params.id);
|
||||
const positionData = {
|
||||
map_x_percent: req.body.map_x_percent,
|
||||
map_y_percent: req.body.map_y_percent,
|
||||
map_width_percent: req.body.map_width_percent,
|
||||
map_height_percent: req.body.map_height_percent
|
||||
};
|
||||
if (req.body.workplace_id !== undefined) positionData.workplace_id = req.body.workplace_id;
|
||||
const eq = await equipmentModel.updateMapPosition(id, positionData);
|
||||
res.json({ success: true, data: eq });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
// ==================== 사진 ====================
|
||||
|
||||
async function addPhoto(req, res, next) {
|
||||
try {
|
||||
const equipmentId = parseInt(req.params.id);
|
||||
if (!req.file) return res.status(400).json({ success: false, error: '사진 파일이 필요합니다' });
|
||||
const photoData = {
|
||||
photo_path: `/uploads/${req.file.filename}`,
|
||||
description: req.body.description || null,
|
||||
display_order: parseInt(req.body.display_order) || 0,
|
||||
uploaded_by: req.user?.user_id || null
|
||||
};
|
||||
const result = await equipmentModel.addPhoto(equipmentId, photoData);
|
||||
res.status(201).json({ success: true, data: result });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
async function getPhotos(req, res, next) {
|
||||
try {
|
||||
const results = await equipmentModel.getPhotos(parseInt(req.params.id));
|
||||
res.json({ success: true, data: results });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
async function deletePhoto(req, res, next) {
|
||||
try {
|
||||
const result = await equipmentModel.deletePhoto(parseInt(req.params.photoId));
|
||||
if (result.photo_path) {
|
||||
const filePath = path.join(__dirname, '..', result.photo_path);
|
||||
fs.unlink(filePath, () => {});
|
||||
}
|
||||
res.json({ success: true, message: '사진이 삭제되었습니다' });
|
||||
} catch (err) { next(err); }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getAll, getById, getByWorkplace, create, update, remove, getTypes, getNextCode,
|
||||
updateMapPosition,
|
||||
addPhoto, getPhotos, deletePhoto
|
||||
};
|
||||
Reference in New Issue
Block a user