feat: 권한 탭 분리 + 부서 인원 표시 + 다수 시스템 개선
- tkuser: 권한 관리를 별도 탭으로 분리, 부서 클릭 시 소속 인원 목록 표시 - system1: 모바일 UI 개선, nginx 권한 보정, 신고 카테고리 타입 마이그레이션 - system2: 신고 상세/보고서 개선, 내 보고서 페이지 추가 - system3: 이슈 뷰/수신함/관리함 개선 - gateway: 포털 라우팅 수정 - user-management API: 부서별 권한 벌크 설정 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -272,6 +272,20 @@ exports.createReport = async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
// category_type 조회
|
||||
let categoryType = null;
|
||||
try {
|
||||
const catInfo = await new Promise((resolve, reject) => {
|
||||
workIssueModel.getCategoryById(issue_category_id, (catErr, data) => {
|
||||
if (catErr) reject(catErr); else resolve(data);
|
||||
});
|
||||
});
|
||||
if (catInfo) categoryType = catInfo.category_type;
|
||||
} catch (catErr) {
|
||||
console.error('카테고리 조회 실패:', catErr);
|
||||
return res.status(500).json({ success: false, error: '카테고리 정보 조회 실패' });
|
||||
}
|
||||
|
||||
const reportData = {
|
||||
reporter_id,
|
||||
factory_category_id: factory_category_id || null,
|
||||
@@ -282,6 +296,7 @@ exports.createReport = async (req, res) => {
|
||||
visit_request_id: visit_request_id || null,
|
||||
issue_category_id,
|
||||
issue_item_id: finalItemId || null,
|
||||
category_type: categoryType,
|
||||
additional_description: additional_description || null,
|
||||
...photoPaths
|
||||
};
|
||||
@@ -326,6 +341,26 @@ exports.createReport = async (req, res) => {
|
||||
|
||||
const descText = additional_description || categoryInfo.category_name;
|
||||
|
||||
// 위치 정보 조회
|
||||
let locationInfo = custom_location || null;
|
||||
if (factory_category_id) {
|
||||
try {
|
||||
const locationParts = await new Promise((resolve, reject) => {
|
||||
workIssueModel.getLocationNames(factory_category_id, workplace_id, (locErr, data) => {
|
||||
if (locErr) reject(locErr); else resolve(data);
|
||||
});
|
||||
});
|
||||
if (locationParts) {
|
||||
locationInfo = locationParts.factory_name || '';
|
||||
if (locationParts.workplace_name) {
|
||||
locationInfo += ` - ${locationParts.workplace_name}`;
|
||||
}
|
||||
}
|
||||
} catch (locErr) {
|
||||
console.error('위치 정보 조회 실패:', locErr.message);
|
||||
}
|
||||
}
|
||||
|
||||
// 원래 신고자의 SSO 토큰 추출
|
||||
const originalToken = (req.headers['authorization'] || '').replace('Bearer ', '');
|
||||
|
||||
@@ -335,6 +370,7 @@ exports.createReport = async (req, res) => {
|
||||
reporter_name: req.user.name || req.user.username,
|
||||
tk_issue_id: reportId,
|
||||
project_id: project_id || null,
|
||||
location_info: locationInfo,
|
||||
photos: photoBase64List,
|
||||
ssoToken: originalToken
|
||||
});
|
||||
@@ -667,6 +703,30 @@ exports.getStatusLogs = (req, res) => {
|
||||
});
|
||||
};
|
||||
|
||||
// ==================== 유형 이관 ====================
|
||||
|
||||
/**
|
||||
* 신고 유형 이관
|
||||
*/
|
||||
exports.transferReport = (req, res) => {
|
||||
const { id } = req.params;
|
||||
const { category_type } = req.body;
|
||||
|
||||
// ENUM 유효성 검증
|
||||
const validTypes = ['nonconformity', 'safety', 'facility'];
|
||||
if (!category_type || !validTypes.includes(category_type)) {
|
||||
return res.status(400).json({ success: false, error: '유효하지 않은 유형입니다. (nonconformity, safety, facility)' });
|
||||
}
|
||||
|
||||
workIssueModel.transferCategoryType(id, category_type, req.user.user_id, (err, result) => {
|
||||
if (err) {
|
||||
console.error('유형 이관 실패:', err);
|
||||
return res.status(400).json({ success: false, error: err.message || '유형 이관 실패' });
|
||||
}
|
||||
res.json({ success: true, message: '유형이 이관되었습니다.' });
|
||||
});
|
||||
};
|
||||
|
||||
// ==================== 통계 ====================
|
||||
|
||||
/**
|
||||
@@ -674,6 +734,7 @@ exports.getStatusLogs = (req, res) => {
|
||||
*/
|
||||
exports.getStatsSummary = (req, res) => {
|
||||
const filters = {
|
||||
category_type: req.query.category_type,
|
||||
start_date: req.query.start_date,
|
||||
end_date: req.query.end_date,
|
||||
factory_category_id: req.query.factory_category_id
|
||||
|
||||
Reference in New Issue
Block a user